Как использовать строки файла в качестве аргументов команды? - PullRequest
121 голосов
/ 19 ноября 2010

Скажем, у меня есть файл foo.txt, в котором указаны N аргументы

arg1
arg2
...
argN

, которые мне нужно передать в команду my_command

Как использовать строкифайл в качестве аргументов команды?

Ответы [ 7 ]

185 голосов
/ 19 ноября 2010

Если ваша оболочка - bash (среди прочих), ярлык для $(cat afile) - $(< afile), поэтому вы должны написать:

mycommand "$(< file.txt)"

Документировано на странице руководства bash в «Подстановке команд»'section.

С другой стороны, ваша команда должна читать из стандартного ввода, поэтому: mycommand < file.txt

35 голосов
/ 20 ноября 2010

Как уже упоминалось, вы можете использовать обратные метки или $(cat filename).

Что не было упомянуто, и я думаю, важно отметить, что вы должны помнить, что оболочка будет разбивать содержимоеэтот файл в соответствии с пробелами, давая каждое слово, которое он находит в вашей команде в качестве аргумента.И хотя вы можете заключить аргумент командной строки в кавычки, чтобы он мог содержать пробелы, escape-последовательности и т. Д., Чтение из файла не будет делать то же самое.Например, если ваш файл содержит:

a "b c" d

, вы получите следующие аргументы:

a
"b
c"
d

Если вы хотите использовать каждую строку в качестве аргумента, используйте while / read /сделать конструкцию:

while read i ; do command_name $i ; done < filename
15 голосов
/ 19 ноября 2010

Вы делаете это с помощью обратных галочек:

echo World > file.txt
echo Hello `cat file.txt`
14 голосов
/ 20 ноября 2010
command `< file`

передаст содержимое файла команде на stdin, но уберет символы новой строки, что означает, что вы не можете перебирать каждую строку по отдельности.Для этого вы можете написать скрипт с циклом for:

for i in `cat input_file`; do some_command $i; done
6 голосов
/ 10 января 2016

Вот как я передаю содержимое файла в качестве аргумента команды:

./foo --bar "$(cat ./bar.txt)"
6 голосов
/ 20 марта 2014

Если вы хотите сделать это надежным способом, который работает для каждого возможного аргумента командной строки (значения с пробелами, значения с символами новой строки, значения с буквенными символами кавычек, непечатные значения, значения с символами глобуса и т. Д.), Онстановится немного интереснее.


Для записи в файл, заданный массив аргументов:

printf '%s\0' "${arguments[@]}" >file

... заменить на "argument one", "argument two" и т. д.* при необходимости.


Для чтения из этого файла и использования его содержимого (в bash, ksh93 или другой недавней оболочке с массивами):

declare -a args=()
while IFS='' read -r -d '' item; do
  args+=( "$item" )
done <file
run_your_command "${args[@]}"

Для чтенияиз этого файла и использовать его содержимое (в оболочке без массивов; обратите внимание, что это перезапишет ваш локальный список аргументов командной строки, и, следовательно, лучше всего это сделать внутри функции, так что вы перезаписываете аргументы функции, а не глобальныеlist):

set --
while IFS='' read -r -d '' item; do
  set -- "$@" "$item"
done <file
run_your_command "$@"

Обратите внимание, что -d (допускающий использование другого разделителя конца строки) является расширением, отличным от POSIX, и оболочка без массивов может также не поддерживать его.В этом случае вам может понадобиться использовать язык без оболочки для преобразования содержимого, разделенного NUL, в eval -безопасную форму:

quoted_list() {
  ## Works with either Python 2.x or 3.x
  python -c '
import sys, pipes, shlex
quote = pipes.quote if hasattr(pipes, "quote") else shlex.quote
print(" ".join([quote(s) for s in sys.stdin.read().split("\0")][:-1]))
  '
}

eval "set -- $(quoted_list <file)"
run_your_command "$@"
3 голосов
/ 20 марта 2014

В моей оболочке bash следующее работает как шарм:

cat input_file | xargs -I % sh -c 'command1 %; command2 %; command3 %;'

, где input_file -

arg1
arg2
arg3

Как видно, это позволяет вам выполнять несколько команд с каждой строкой из input_file, хороший маленький трюк, который я изучил здесь .

...