Скажем, у меня есть файл с foo.txt
указанием N
аргументов
arg1
arg2
...
argN
который мне нужно передать в команду my_command
Как использовать строки файла в качестве аргументов команды?
Скажем, у меня есть файл с foo.txt
указанием N
аргументов
arg1
arg2
...
argN
который мне нужно передать в команду my_command
Как использовать строки файла в качестве аргументов команды?
Ответы:
Если ваша оболочка - bash (среди прочих), ярлык для нее
$(cat afile)
есть$(< afile)
, поэтому вы должны написать:Документировано на странице руководства bash в разделе «Подстановка команд».
В качестве альтернативы сделайте так, чтобы ваша команда читала из stdin, поэтому:
mycommand < file.txt
источник
<
оператора. Это означает, что сама оболочка будет выполнять перенаправление, а не выполнятьcat
двоичный файл для своих свойств перенаправления."$(…)"
него содержимоеfile.txt
будет передано на стандартный вводmycommand
, а не в качестве аргумента."$(…)"
означает запустить команду и вернуть результат в виде строки ; здесь «команда» только читает файл, но он может быть более сложным.Как уже упоминалось, вы можете использовать обратные кавычки или
$(cat filename)
.Что не было упомянуто, и я думаю, что важно отметить, это то, что вы должны помнить, что оболочка будет разбивать содержимое этого файла в соответствии с пробелами, передавая каждое «слово», которое она находит, вашей команде в качестве аргумента. И хотя вы можете заключить аргумент командной строки в кавычки, чтобы он мог содержать пробелы, escape-последовательности и т. Д., Чтение из файла не будет делать то же самое. Например, если ваш файл содержит:
аргументы, которые вы получите:
Если вы хотите использовать каждую строку в качестве аргумента, используйте конструкцию while / read / do:
источник
read -r
если только вы не хотите расширять последовательности с обратной косой чертой - и NUL является более безопасным разделителем, чем символ новой строки, особенно если передаваемые вами аргументы являются такими, как имена файлов, которые могут содержать буквальные символы новой строки. Кроме того, без очистки IFS вы получаете неявно очищенные начальные и конечные пробелыi
.передаст содержимое файла команде на stdin, но удалит символы новой строки, что означает, что вы не можете перебирать каждую строку отдельно. Для этого вы можете написать скрипт с циклом for:
Или (многострочный вариант):
Или (многострочный вариант с
$()
вместо``
):Ссылки:
источник
< file
вставка обратных кавычек означает, что на самом деле перенаправление вообще не выполняетсяcommand
.command `< file`
Не работает ни в bash, ни в POSIX sh; zsh - это другое дело, но речь идет не о оболочке, о которой идет речь).Hello World
на одну строчку. Вы увидите , что сначала запуститьsome_command Hello
, а затемsome_command World
, неsome_command "Hello World"
илиsome_command Hello World
.Вы делаете это с помощью обратных галочек:
источник
echo "Hello * Starry * World" > file.txt
первый шаг, вы получите как минимум четыре отдельных аргумента, переданных второй команде - и, вероятно, больше, поскольку*
s расширится до имен файлов, присутствующих в текущем каталоге.fork()
извлекает вложенную оболочку с FIFO, присоединенной к его стандартному выводу, затем вызывается/bin/cat
как дочерний элемент этой вложенной оболочки, а затем читает вывод через FIFO; сравните с$(<file.txt)
, который считывает содержимое файла непосредственно в bash без вложенных оболочек или FIFO.Если вы хотите сделать это надежным способом, который работает для каждого возможного аргумента командной строки (значения с пробелами, значения с символами новой строки, значения с буквенными символами кавычек, непечатные значения, значения с символами глобуса и т. Д.), Он получает немного интереснее.
Для записи в файл предоставляется массив аргументов:
... заменить
"argument one"
,"argument two"
и т.д. в зависимости от обстоятельств.Чтобы прочитать из этого файла и использовать его содержимое (в bash, ksh93 или другой недавней оболочке с массивами):
Для чтения из этого файла и использования его содержимого (в оболочке без массивов; обратите внимание, что это перезапишет ваш локальный список аргументов командной строки и, следовательно, лучше всего делать это внутри функции, так что вы перезаписываете аргументы функции, а не глобальный список):
Обратите внимание, что
-d
(допускается использование другого разделителя конца строки) не является расширением POSIX, и оболочка без массивов также может не поддерживать его. В этом случае вам может понадобиться использовать язык без оболочки для преобразования содержимого, разделенного NUL, вeval
форму -safe:источник
Вот как я передаю содержимое файла в качестве аргумента команды:
источник
$(<bar.txt)
(при использовании оболочки, такой как bash, с соответствующим расширением).$(<foo)
это особый случай: в отличие от обычной подстановки команд, используемой в$(cat ...)
, она не раскладывает подоболочку для работы и, таким образом, избегает значительных накладных расходов.Если все, что вам нужно сделать, это превратить файл
arguments.txt
с содержимымв
my_command arg1 arg2 argN
то время вы можете просто использоватьxargs
:Вы можете добавить дополнительные статические аргументы в
xargs
вызов, напримерxargs -a arguments.txt my_command staticArg
, вызовmy_command staticArg arg1 arg2 argN
источник
В моей оболочке bash следующее работает как шарм:
где input_file
Как видно, это позволяет вам выполнять несколько команд с каждой строкой из input_file, милую небольшую хитрость, которую я здесь изучил .
источник
$(somecommand)
, вы получите эту команду выполненной, а не переданной в виде текста. Аналогично,>/etc/passwd
будет обрабатываться как перенаправление и перезапись/etc/passwd
(если запускаться с соответствующими разрешениями) и т. Д.xargs -d $'\n' sh -c 'for arg; do command1 "$arg"; command2 "arg"; command3 "arg"; done' _
- и также более эффективно, поскольку он передает столько аргументов каждой оболочке, сколько возможно, вместо запуска одной оболочки на строку во входном файле.cat
После редактирования ответа @Wesley Райс пару раз, я решил мои изменения были просто становятся слишком большими , чтобы продолжить изменение его ответа , вместо того , чтобы писать самостоятельно. Итак, я решил, что мне нужно написать свой собственный!
Прочитайте каждую строку файла и построчно обработайте его следующим образом:
Это напрямую от автора Vivek Gite здесь: https://www.cyberciti.biz/faq/unix-howto-read-line-by-line-from-file/ . Он получает кредит!
А теперь, чтобы ответить на этот теперь закрытый вопрос, который у меня тоже был: возможно ли `git add` список файлов из файла? - вот мой ответ:
Обратите внимание, что
FILES_STAGED
это переменная, содержащая абсолютный путь к файлу, который содержит набор строк, где каждая строка является относительным путем к файлу, с которым я хотел бы работатьgit add
. Этот фрагмент кода собирается стать частью файла «eRCaGuy_dotfiles / полезно_scripts / sync_git_repo_to_build_machine.sh» в этом проекте, чтобы упростить синхронизацию файлов в процессе разработки с одного ПК (например, компьютер, на котором я кодирую) на другой (например, a более мощный компьютер, на котором я работаю): https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles .Ссылки:
Связанный:
git add
на нем: возможно ли `git add` список файлов из файла?источник