Как преобразовать содержимое файла в аргумент для команды Unix?
Включение аргумента в содержимое файла выполняется следующим образом:
echo ABC > file.txt
Но другое направление?
Как преобразовать содержимое файла в аргумент для команды Unix?
Включение аргумента в содержимое файла выполняется следующим образом:
echo ABC > file.txt
Но другое направление?
Если ваша оболочка bash (среди прочих), ярлык для $(cat afile)
- $(< afile)
, поэтому вы должны написать:
mycommand "$(< file.txt)"
Документируется в справочной странице bash в разделе "Замена команд".
В противном случае попробуйте прочитать команду stdin, поэтому: mycommand < file.txt
Как уже упоминалось, вы можете использовать backticks или $(cat filename)
.
Что не упоминалось, и я думаю, важно отметить, что вы должны помнить, что оболочка будет разрывать содержимое этого файла в соответствии с пробелом, предоставляя каждое "слово", которое оно находит в вашей команде в качестве аргумента. И хотя вы можете заключить аргумент командной строки в кавычки, чтобы он мог содержать пробелы, escape-последовательности и т.д., Чтение из файла не будет делать то же самое. Например, если ваш файл содержит:
a "b c" d
аргументы, которые вы получите:
a
"b
c"
d
Если вы хотите вывести каждую строку в качестве аргумента, используйте конструкцию while/read/do:
while read i ; do command_name $i ; done < filename
Вы делаете это с помощью backticks:
echo World > file.txt
echo Hello `cat file.txt`
command `< file`
передаст содержимое файла команде stdin, но разделит строки, что означает, что вы не можете перебирать каждую строку по отдельности. Для этого вы можете написать script с циклом 'for':
for i in `cat input_file`; do some_command $i; done
Если вы хотите сделать это надежным способом, который работает для каждого возможного аргумента командной строки (значения с пробелами, значениями с символами новой строки, значениями с буквальными символами кавычек, значениями, не подлежащими печати, значениями с символами glob и т.д.), это становится немного интереснее.
Чтобы записать в файл, задайте массив аргументов:
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[@]}"
Чтобы прочитать из этого файла и использовать его содержимое (в оболочке без массивов, обратите внимание, что это перезапишет ваш локальный список аргументов командной строки и, таким образом, лучше всего сделать внутри функции, так что вы перезаписываете функцию аргументы, а не глобальный список):
set --
while IFS='' read -r -d '' item; do
set -- "[email protected]" "$item"
done <file
run_your_command "[email protected]"
Обратите внимание, что -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 "[email protected]"
Вот как я передаю содержимое файла в качестве аргумента команде:
./foo --bar "$(cat ./bar.txt)"
В моей оболочке bash следующее работало как шарм:
cat input_file | xargs -I % sh -c 'command1 %; command2 %; command3 %;'
где input_file
arg1
arg2
arg3
Как очевидно, это позволяет вам выполнять несколько команд с каждой строкой из input_file, хороший небольшой трюк, который я узнал здесь.