Может кто-нибудь, пожалуйста, предоставьте код, чтобы сделать следующее: Предположим, что есть каталог файлов, все из которых нужно запускать через программу. Программа выводит результаты на стандарт. Мне нужен script, который войдет в каталог, выполнит команду для каждого файла и разделит вывод на один большой выходной файл.
Например, для запуска команды в 1 файл:
$ cmd [option] [filename] > results.out
Следующий bash код передаст $file для команды, где $file будет представлять каждый файл в каталоге /dir
for file in /dir/*
do
cmd [option] "$file" >> results.out
done
Пример
el@defiant ~/foo $ touch foo.txt bar.txt baz.txt
el@defiant ~/foo $ for i in *.txt; do echo "hello $i"; done
hello bar.txt
hello baz.txt
hello foo.txt
/dir/
нет файлов, то цикл все равно выполняется один раз со значением '*' для $file
, что может быть нежелательно. Чтобы избежать этого, включите nullglob на время цикла. Добавьте эту строку перед циклом shopt -s nullglob
и эту строку после цикла shopt -u nullglob #revert nullglob back to it's normal default state
.
Как насчет этого:
find /some/directory -maxdepth 1 -type f -exec cmd option {} \; > results.out
-maxdepth 1
не позволяет найти из рекурсивного спуска в
любые подкаталоги. (Если вы хотите, чтобы такие вложенные каталоги обрабатывались, вы можете опустить это.)-type -f
указывает, что будут обрабатываться только простые файлы.-exec cmd option {}
сообщает, что он запускает cmd
с указанным option
для каждого найденного файла, при этом имя файла заменяется на {}
\;
обозначает конец команды.cmd
исполнений перенаправляется на
results.out
Однако, если вы заботитесь о порядке обработки файлов, вы
может быть лучше писать петлю. Я думаю, что find
обрабатывает файлы
в порядке inode (хотя я мог ошибаться в этом), что может и не быть
вы хотите.
stat
и sort
, что, конечно, зависит от критериев сортировки.
-exec
? Должен ли я обернуть их в одинарные кавычки или что-то?
Я делаю это на моем малине pi из командной строки, запустив:
for i in *;do omxplayer "$i";done
Один быстрый и грязный способ, который иногда выполняет эту работу:
find directory/ | xargs Command
Например, чтобы найти количество строк во всех файлах в текущем каталоге, вы можете:
find . | xargs wc -l
Основываясь на подходе @Jim Lewis:
Вот быстрое решение, использующее find
, а также сортировку файлов по дате их изменения:
$ find directory/ -maxdepth 1 -type f -print0 | \
xargs -r0 stat -c "%y %n" | \
sort | cut -d' ' -f4- | \
xargs -d "\n" -I{} cmd -op1 {}
Для сортировки см.
http://www.commandlinefu.com/commands/view/5720/find-files-and-list-them-sorted-by-modification-time
-print0
для find
и -0
для xargs
которые используют нулевой символ вместо пробела (включая символы новой строки).
Мне нужно было скопировать все файлы .md из одного каталога в другой, вот что я сделал.
for i in **/*.md;do mkdir -p ../docs/"$i" && rm -r ../docs/"$i" && cp "$i" "../docs/$i" && echo "$i -> ../docs/$i"; done
Это довольно трудно прочитать, поэтому давайте сломаем его.
первый cd в каталог с вашими файлами,
for i in **/*.md;
для каждого файла в вашем шаблоне
mkdir -p ../docs/"$i"
сделать этот каталог в папке docs за пределами папки, содержащей ваши файлы. Что создает дополнительную папку с тем же именем, что и этот файл.
rm -r ../docs/"$i"
удалите дополнительную папку, созданную в результате mkdir -p
cp "$i" "../docs/$i"
Скопировать фактический файл
echo "$i -> ../docs/$i"
Эхо, что ты сделал
; done
Жить счастливо после
**
необходимо установить globstar
оболочки shopt -s globstar
: shopt -s globstar
ls <directory> | xargs cmd [options] {filenames put in here automatically by xargs} [more arguments] > results.out
ls
для управленияxargs
. Еслиcmd
написан грамотно, возможно, вы можете просто использоватьcmd <wildcard>
.