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