Я хотел бы запустить:
./a.out < x.dat > x.ans
для каждого * .dat файла в каталоге A .
Конечно, это может быть сделано скриптом bash / python / whatSever, но мне нравится писать сексуальные однострочные. Все, чего я мог достичь, это (все еще без какого-либо стандартного выхода)
ls A/*.dat | xargs -I file -a file ./a.out
Но -a в xargs не понимает файл-замены replace-str.
Спасибо за помощь.
io-redirection
xargs
Николай Вяххи
источник
источник
Ответы:
Прежде всего, не используйте
ls
вывод как список файлов . Используйте расширение оболочки илиfind
. Ниже приведены возможные последствия неправильного использования ls + xargs и пример правильногоxargs
использования.1. Простой способ: для цикла
Если вы хотите обрабатывать только файлы, расположенные ниже
A/
, то простогоfor
цикла должно быть достаточно:2. pre1 Почему бы и нет
ls | xargs
?Вот пример того, как плохие вещи могут обернуться, если вы используете
ls
сxargs
для работы. Рассмотрим следующий сценарий:во-первых, давайте создадим несколько пустых файлов:
посмотрите файлы и чтобы они ничего не содержали:
запустить магическую команду, используя
xargs
:результат:
Так что вам только что удалось перезаписать и то
mypreciousfile.dat
и другоеmypreciousfile.dat.ans
. Если бы в этих файлах было какое-либо содержимое, оно было бы стерто.2. Использование
xargs
: правильно сfind
Если вы хотите настаивать на использовании
xargs
, используйте-0
(имена, оканчивающиеся нулем):Обратите внимание на две вещи:
.dat.ans
окончанием;"
).Обе проблемы могут быть решены с помощью различных способов вызова оболочки:
3. Все сделано в течение
find ... -exec
Это, опять же, производит
.dat.ans
файлы и сломается, если имена файлов содержат"
. Для этого используйтеbash
и измените способ его вызова:источник
zsh
используется в качестве оболочки (а SH_WORD_SPLIT не установлен), все неприятные особые случаи (пробелы, "в имени файла и т. Д.) Не должны рассматриваться. Тривиальныйfor file in A/*.dat; do ./a.out < $file > ${file%.dat}.ans ; done
работает во всех случаях.find
.Попробуйте сделать что-то вроде этого (синтаксис может немного отличаться в зависимости от используемой оболочки):
$ for i in $(find A/ -name \*.dat); do ./a.out < ${i} > ${i%.dat}.ans; done
источник
somefile.dat.dat
и перенаправить весь вывод в один файл.somefile.dat.ans
вывод материала будет выглядеть не так хорошо.-type file
было бы хорошо (не может< directory
), и это делает фею необычного имени файла печальной.Для простых шаблонов подходит цикл for:
Для более сложных случаев, когда вам нужна другая утилита для вывода списка файлов (zsh или bash 4 имеют достаточно мощные шаблоны, которые вам редко нужно находить, но если вы хотите остаться в оболочке POSIX или использовать быструю оболочку, такую как dash, вам понадобится найти что-нибудь нетривиально), хотя чтение наиболее уместно:
Это будет обрабатывать пробелы, потому что чтение (по умолчанию) ориентировано на строки. Он не будет обрабатывать символы новой строки и не будет обрабатывать обратную косую черту, потому что по умолчанию он интерпретирует escape-последовательности (что фактически позволяет передавать символы новой строки, но команда find не может сгенерировать этот формат). Многие оболочки имеют
-0
опцию для чтения, поэтому в них вы можете обрабатывать все символы, но, к сожалению, это не POSIX.источник
Используйте GNU Parallel:
Дополнительный бонус: обработка выполняется параллельно.
Посмотрите вступительные видео, чтобы узнать больше: http://www.youtube.com/watch?v=OpaiGYxkSuQ
источник
Я думаю, что вам нужно, по крайней мере, вызов оболочки в xargs:
Изменить: Следует отметить, что этот подход не работает, когда имена файлов содержат пробелы. Не могу работать Даже если бы вы использовали команды find -0 и xargs -0, чтобы xargs правильно понимал пробелы, вызов оболочки -c обрушился бы на них. Однако OP явно попросил решение xargs, и это лучшее решение xargs, которое я придумал. Если пробелы в именах файлов могут быть проблемой, используйте find -exec или цикл оболочки.
источник
ls
вывод .ls
выход можно такие вещи , как пространства , не избежать и что это проблема.ls
не годится. Ноxargs
можно безопасно использовать с find - см. Предложение № 2 в моем ответе.Там нет необходимости усложнять это. Вы можете сделать это с помощью
for
цикла:${file%.dat}.ans
бит будет удалить.dat
суффикс имени файла из файла в$file
и вместо того, чтобы добавить.ans
в конец.источник