Тому що, як ви кажете, вхід 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 *
який відповість рядком для кожного файлу, папки.