Многократный запуск команды с аргументами (именами файлов) из файла?

Вы можете подключиться к leafpad. Я не знаю, есть ли порт для Mac.

4
10.01.2017, 01:11
7 ответов

Я обычно предпочитаю переносимые (POSIX) решения, но простой и очевидный ответ здесь - использовать расширения GNU, чтобы облегчить вашу жизнь:

find . -type f -name '*.txt' -print0 | sort -z | xargs -n1 -r0 ./mycommand

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

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

3
27.01.2020, 20:47

Удобно, xargs -I делает именно то, что вы хотите:

$ xargs <my_file_list.txt -I filename ./my_command "filename"
 -I replace-str 
Заменить вхождения replace-str в начальных аргументах именами, прочитанными 
из стандартного ввода. 
Кроме того, пробелы без кавычек не завершают элементы ввода ; 
вместо этого разделителем является символ новой строки. 
Подразумевает -x и -L 1. 
 

Это означает, что требуется ровно одна строка ввода, разделенная новой строкой, и вызывать вашу команду с этим как единственный аргумент. Ничто, кроме новой строки, не рассматривается как разделитель, поэтому можно использовать пробелы и другие специальные символы.

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

5
27.01.2020, 20:47
sed < list_of_files 's,^,./mycommand ",;s,$,",' | sh
1
27.01.2020, 20:47
$ cat baard.in
/path/to/some space file
/some   tabbed/some     tabbed  file
/path to/genericfile
/path/to/regular.file
/path/to/exciting!/file!
/path/to/(parenthetical)/file.txt

$ cat my_command
#!/bin/sh
printf "my_command: %s\n" "$1"

Поскольку awk уже анализирует строки, вы можете использовать его для вызова своей команды с каждой записью, стараясь заключить параметр в кавычки:

$ awk '{system("./my_command '\''" $0 "'\''");}' < baard.in
my_command: /path/to/some space file
my_command: /some       tabbed/some     tabbed  file
my_command: /path to/genericfile
my_command: /path/to/regular.file
my_command: /path/to/exciting!/file!
my_command: /path/to/(parenthetical)/file.txt

Команда awk не работает если во входных данных есть одинарные кавычки, например:

/books/Hitchhiker's Guide to the Galaxy.epub

Если у вас есть bash, вы можете использовать:

$ readarray -t paths < baard.in
$ for((i=0;i < ${#paths[*]}; i++)); do ./my_command "${paths[i]}"; done
my_command: /path/to/some space file
my_command: /some       tabbed/some     tabbed  file
my_command: /path to/genericfile
my_command: /path/to/regular.file
my_command: /path/to/exciting!/file!
my_command: /path/to/(parenthetical)/file.txt
my_command: /books/Hitchhiker's Guide to the Galaxy.epub

или в ksh93 (подсказка к ответ Жиля здесь для ручная реализация readarray):

$ IFS=$'\n'; set -f
$ paths=( $(< baard.in) )
$ unset IFS; set +f
$ for((i=0;i < ${#paths[*]}; i++)) do ./my_command "${paths[i]}"; done
my_command: /path/to/some space file
my_command: /some       tabbed/some     tabbed  file
my_command: /path to/genericfile
my_command: /path/to/regular.file
my_command: /path/to/exciting!/file!
my_command: /path/to/(parenthetical)/file.txt
my_command: /books/Hitchhiker's Guide to the Galaxy.epub
1
27.01.2020, 20:47

Насколько я понимаю, вы спросили, как читать файл infile и запускать задачу для каждой прочитанной строки.

while IFS= read -r line
do    mycmd "$line"
done  < infile

или если вы хотите сначала отсортировать ввод:

sort ./infile[123] |
while IFS= read -r line
do    mycmd "$line"
done
0
27.01.2020, 20:47

Я предполагаю, что ваш список файлов хранится в файле с именем 'filelist.txt', каждое имя файла в строке. Тогда вы можете вызвать ваш скрипт с каждой строкой в качестве аргумента следующим образом:

while read name; do
  ./yoursrcipt.sh "$name"
done <filelist.txt
2
27.01.2020, 20:47

Если я правильно понял ваш вопрос, что-то вроде этого должно сделать то, что вам нужно (предполагая, что ваш файл имеет одно имя файла в строке):

for i in `cat list_of_files`; do ./mycommand "$i"; done
0
27.01.2020, 20:47

Теги

Похожие вопросы