2013-07-25 2 views
4

Рассмотрим имея результаты из трубы:Получить аргумент из трубы

find . 

Теперь я хотел бы получить доступ во второй команде за трубой, что на самом деле по трубопроводу (занесены), а затем, например, напечатать его в два раза ,

find . | printf $arg$arg\n 
#each filename would be printed twice per line 

Пожалуйста, обратите внимание, что вопрос не прошу о печати все, что когда-то получает от трубы в два раза, я знаю, как использовать Баш для цикла или написать скрипт, который может выполнить упомянутым. Как я могу получить $ arg, чтобы использовать его быстро в встроенных скриптах?

$ 0 и $ 1 не работают так, как в скриптовых файлах.

ответ

5

Короткий ответ: Вы можете распечатать каждый файл дважды с использованием СЭД:

find . | sed 's/.*/& &/' 

Sed может редактировать строки, как они вводятся. Вышеуказанная команда говорит s (заменить) .* (вся строка) & & (с собой, дважды).

Более длинный ответ: Когда труба одна программа в другую, вы подключаетесь стандартный выходной поток первой программы для стандартного входного потока второго программы. Все, что печатает первая программа, будет рассматриваться как вход для второй программы.

К сожалению, для вашего примера входные данные не входят в линейные фрагменты, которые хорошо сопоставляются с гипотетической переменной $args. Он поставляется в большом монолитном потоке. Если вы хотите дважды печатать каждую строку потока, вы можете использовать sed (который является Редактором потока), но он просто выполняет по очереди замену.

6

Игнорирование вероятность того, что имена файлов содержат символы новой строки, вы можете использовать sed в pringley предлагает в своем answer, или вы можете создать while цикл с read команды:

find . | 
while read -r line 
do 
    echo "$line$line" 
done 

(-r для «сырые ', он останавливает оболочку, расширяющую управляющие последовательности обратной косой черты на входе, и является стандартной функцией POSIX команды read в оболочке.)

Поскольку вы упомянули bash, вы c избежать проблем с символами новой строки в именах файлов, используя опцию find . -print0 прекратить каждое имя по нулевой байт ('\0' в C) вместо символа новой строки, а затем использовать:

find . -print0 | 
while read -r -d '' line 
do 
    echo "X${line}${line}X" 
done 

-d '' заменяет нормальный перевод строки разделитель с первым символом строкового аргумента, но строка пуста, поэтому первым символом является единственный символ - нулевой байт.

Существует не легкий путь (и, насколько я знаю, трудный путь), чтобы использовать for петли вдоль линий:

for line in $(find .) 
do 
    echo "X${line}${line}X" 
done 

, который работает надежно для имен с пробелами, или новые строки в них.

Часто вы можете использовать команду xargs. Это считывает стандартный ввод и создает командную строку, используя то, что читается со стандартного ввода в качестве аргументов команды.

find . | xargs wc -l 

Или, с новой строки и безопасности пространства (по умолчанию xargs разбивает аргументы на пространствах, вкладки и переводы строк):

find . -type f -print0 | xargs -0 wc -l 

Есть много вариантов, вы можете обратиться к xargs - особенно Версия GNU.

Однако, у вас также есть варианты для find, которые в основном делают xargs излишним:

find . -type f -exec wc -l {} + 

, который делает в основном ту же работу, что и команда find . -print0 | xargs -0 wc -l. Одно из отличий заключается в том, что если в выводе нет файлов в find, то использование -exec не будет исполнено wc, тогда как по умолчанию xargs выполнит его один раз (без аргумента имени файла, это для соответствия POSIX). С помощью GNU xargs вы можете использовать -r или --no-run-if-empty, чтобы остановить это. Mac OS X xargs похоже, все равно.

3
find . | xargs -I{} printf "%s%s\n" {} {} 
+0

Рассмотрите вопрос "найти. | xargs -I {} printf "% s между% s \ n" {} {} ', попробуйте, что бы напечатать? –

+1

Если вы не оставите пробел между '{}' и '{}', я ожидаю, что он будет печатать "./file./file между". Если там * есть * пробел, я бы ожидал «./file между ./file» –

+0

Я вижу, это правильно, я не знал, для чего нужны фигурные скобки. –