труба, затем дефис (STDIN) в качестве альтернативы для цикла - PullRequest
0 голосов
/ 21 февраля 2020

Я написал несколько команд sed a awk для извлечения набора идентификаторов, связанных с именами файлов. Я хотел бы запустить набор команд, используя эти имена файлов из id.txt

cat id.txt

14235.gz
41231.gz
41234.gz

Я обычно пишу для циклов следующим образом:

for i in $(cat id.txt);
do 
    command <options> $i
done

Я думал, что мог бы также сделать cat id.txt | command <options> -

Есть ли способ передать вывод команды cat, awk, sed, et c, строка за строкой в ​​команду?

Ответы [ 4 ]

2 голосов
/ 21 февраля 2020

Использовать некоторое время для чтения l oop см. Не читать строки со словами

while IFS= read -r line_in_text_file; do
 echo "$line_in_text_file"
done < id.txt
1 голос
/ 21 февраля 2020

xargs может сделать это

cat id.txt | xargs command

От xargs справка

$ xargs --help
Usage: xargs [OPTION]... COMMAND [INITIAL-ARGS]...
Run COMMAND with arguments INITIAL-ARGS and more arguments read from input.

Mandatory and optional arguments to long options are also
mandatory or optional for the corresponding short option.
  -0, --null                   items are separated by a null, not whitespace;
                                 disables quote and backslash processing and
                                 logical EOF processing
  -a, --arg-file=FILE          read arguments from FILE, not standard input
  -d, --delimiter=CHARACTER    items in input stream are separated by CHARACTER,
                                 not by whitespace; disables quote and backslash
...
1 голос
/ 21 февраля 2020

Есть ли способ передать вывод команды cat, awk, sed, et c, строка за строкой в ​​команду?

Сложные команды можно поместить в канал синтаксис не очень строг. Обычное:

awk 'some awk script' |
while IFS= read -r line; do
    echo "$line"
done |
sed 'some sed script'

Я стараюсь не читать строку ввода построчно, используя while read - это очень медленно. Использовать awk сценарии и другие команды намного быстрее.

Группы команд можно использовать для:

awk 'some awk script' |
{     # or '(', but there is no need for a subshell
      echo "header1,header2"
      # remove first line
      IFS= read -r first_line
      # ignore last line
      sed '$d'
} |
sed 'some sed script'

Помните, что команда pipe запускается в подоболочке, поэтому изменения переменных не будут влияет на родительскую оболочку.

Bash имеет расширение замещения процесса, которое позволяет вам некоторое время запустить l oop внутри родительской оболочки:

var=1
while IFS= read -r line; do
     if [[ "$line" == 2 ]]; then
        var=2
      fi
done <(
    seq 10 |
    sed '$d'
)
echo "$var"  # will output 2
1 голос
/ 21 февраля 2020

Команды обычно не получают аргументы своего имени файла при стандартном вводе. Использование - в качестве аргумента означает чтение содержимого файла из стандартного ввода вместо именованного файла, это не означает получение имени файла из стандартного ввода.

Вы можете использовать подстановку команд, чтобы использовать содержимое файл в качестве всех аргументов имени файла команды:

command <options> $(cat id.txt)

или вы можете использовать xargs

xargs command <options> < id.txt
...