"що робить $(ls *.txt)"
Коротка відповідь
$(ls *.txt)збирає список імен файлів, а потім обробляє їх . Ви НЕ використовувати це.
Більш довга відповідь
lsпризначений для людського результату. Як писав один із супровідників Ls у відповідь на те, чому lsб не запропонувати --nullваріант:
Якби ми це робили, то це був би інтерфейс, який ми використовуємо. Однак
lsце справді інструмент прямого споживання людиною , і в цьому випадку подальша обробка є менш корисною. Для подальшої обробки findбільше підходить (1). [наголос додано]
Іншими словами, використання lsдля чогось іншого, крім відображення для людей, просто не підтримується. lsНаприклад, технічні працівники, наприклад, нещодавно змінили вихідний формат за замовчуванням на те, що вони хоч і зручніші для людини без попередження . Отже, дотримуйтесь їхніх порад: якщо ви збираєтеся робити подальшу обробку імен файлів, використовуйте findзамість ls.
$(...)- це підміна команд. Одним із наслідків використання підстановки команд є те, що вилучені символи нового рядка видаляються. Якщо прізвище останнього файлу у списку містить кінцеві нові рядки, вони будуть видалені.
Оскільки текст $(...)не є подвійним цитуванням, текст, який він видає, буде підпорядкований:
Розбиття слів
Розширення шляху
Результатом обох є подальше керування назвами файлів.
не кажучи вже про питання з іменами файлів , починаючи з -з - за якого бракує --(для обох lsі , egrepяк в Ubuntu egrepє реалізація GNU приймає параметри навіть після аргументів , не варіант , якщо POSIXLY_CORRECTне в навколишньому середовищі).
також, якщо будь-який з цих txtфайлів мав типовий каталог , lsвін перелічив би їхній вміст замість себе.
і якщо txtфайлів немає , вихідний файл lsбуде порожнім (хоча ви побачите помилку щодо відсутнього *.txtфайлу) і оскільки egrepне отримаєте аргументу файлу, він шукатиме речі у своєму стандартному вході (і, здавалося б, висить).
Приклад
Створимо 4 файли, що містять Stuffу нашому каталозі:
$ echo Stuff | tee file1 file2 'a b c.txt' 'f* .txt'
Stuff
$ ls -Q
"a b c.txt" "file1" "file2" "f* .txt"
Тепер запустімо команду egrep:
$ egrep "Stuff" $(ls *.txt)
grep: a: No such file or directory
grep: b: No such file or directory
grep: c.txt: No such file or directory
file1:Stuff
file2:Stuff
f* .txt:Stuff
grep: .txt: No such file or directory
Зауважте, що ми отримуємо 4 повідомлення про помилки щодо неіснуючих файлів. Це пов’язано з розщепленням слів . Результат також показує збіги з двома файлами, file1і file2їх не слід було шукати, оскільки вони не закінчуються .txt. Це через розширення _pathname`.
Правильно написана команда створює два успішні збіги і жодних помилок:
$ egrep -- "Stuff" *.txt
a b c.txt:Stuff
f* .txt:Stuff
Рекомендоване рішення
Використання:
egrep -- "Stuff" *.txt
або POSIXly:
grep -E -- "Stuff" *.txt
або:
grep -E -e Stuff -- *.txt
Це буде працювати з будь-яким ім'ям файлу і не має жодного з обмежень lsпідходу.