Потому что, как вы говорите, ввод file
должен быть именами файлов . Вывод ls
, однако, просто текст. То, что это список имен файлов, не меняет того факта, что это просто текст, а не расположение файлов на жестком диске.
Когда вы видите результат печати на экране, вы видите текст. Является ли этот текст стихотворением или списком имен файлов, для компьютера не имеет значения. Все, что он знает, это то, что это текст. Вот почему вы можете передавать выходные данные ls
программам, которые принимают текст в качестве входных данных (хотя вы действительно, действительно, не должны ):
$ ls / | grep etc
etc
Таким образом, чтобы использовать выходные данные команды, которая перечисляет имена файлов в виде текста (например, ls
или find
), в качестве входных данных для команды, которая принимает имена файлов, вам необходимо использовать некоторые приемы. Типичный инструмент для этого xargs
:
$ ls
file1 file2
$ ls | xargs wc
9 9 38 file1
5 5 20 file2
14 14 58 total
Как я уже говорил ранее, вы действительно не хотите анализировать вывод ls
. Что - то вроде find
лучше (то print0
печатает \0
вместо того , newilne после каждого имени файла и -0
из xargs
позволяет ему иметь дело с таким входом, это уловка , чтобы сделать ваши команды работают с именами файлов , содержащих символы новой строки):
$ find . -type f -print0 | xargs -0 wc
9 9 38 ./file1
5 5 20 ./file2
14 14 58 total
Который также имеет свой собственный способ сделать это, без необходимости xargs
вообще:
$ find . -type f -exec wc {} +
9 9 38 ./file1
5 5 20 ./file2
14 14 58 total
Наконец, вы также можете использовать цикл оболочки. Однако учтите, что в большинстве случаев xargs
будет намного быстрее и эффективнее. Например:
$ for file in *; do wc "$file"; done
9 9 38 file1
5 5 20 file2
ls
, это означает, что вы хотите, чтобы все файлы в текущем каталоге обрабатывалисьfile
командой. ... Так почему бы просто не сделать:,file *
который будет отвечать строкой для каждого файла, папки.