найти -exec с несколькими командами - PullRequest
376 голосов
/ 25 февраля 2011

Я пытаюсь использовать find -exec с несколькими командами, но безуспешно. Кто-нибудь знает, возможны ли такие команды, как следующие?

find *.txt -exec echo "$(tail -1 '{}'),$(ls '{}')" \;

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

Ответы [ 9 ]

562 голосов
/ 18 мая 2011

find принимает несколько -exec частей к команде.Например:

find . -name "*.txt" -exec echo {} \; -exec grep banana {} \;

Обратите внимание, что в этом случае вторая команда будет выполняться только в том случае, если первая команда вернется успешно, как упоминалось @Caleb.Если вы хотите, чтобы обе команды выполнялись независимо от их успеха или неудачи, вы можете использовать эту конструкцию:

find . -name "*.txt" \( -exec echo {} \; -o -exec true \; \) -exec grep banana {} \;
82 голосов
/ 07 декабря 2012
find . -type d -exec sh -c "echo -n {}; echo -n ' x '; echo {}" \;
47 голосов
/ 25 февраля 2011

Одно из следующего:

find *.txt -exec awk 'END {print $0 "," FILENAME}' {} \;

find *.txt -exec sh -c 'echo "$(tail -n 1 "$1"),$1"' _ {} \;

find *.txt -exec sh -c 'echo "$(sed -n "\$p" "$1"),$1"' _ {} \;
15 голосов
/ 03 сентября 2017

Другой способ такой:

multiple_cmd() { 
    tail -n1 $1; 
    ls $1 
}; 
export -f multiple_cmd; 
find *.txt -exec bash -c 'multiple_cmd "$0"' {} \;

в одну строку

multiple_cmd() { tail -1 $1; ls $1 }; export -f multiple_cmd; find *.txt -exec bash -c 'multiple_cmd "$0"' {} \;
  • "multiple_cmd()" - это функция
  • "export -f multiple_cmd" - экспортирует его, так что любой другой подоболочек сможет его увидеть
  • "find *.txt -exec bash -c 'multiple_cmd "$0"' {} \;" - найдите, что будет выполнять функцию на вашем примере

Таким образом, multip_cmd может быть настолько длинным и сложным, насколько вам нужно.

Надеюсь, это поможет.

8 голосов
/ 05 июня 2016

Есть более простой способ:

find ... | while read -r file; do
    echo "look at my $file, my $file is amazing";
done

В качестве альтернативы:

while read -r file; do
    echo "look at my $file, my $file is amazing";
done <<< "$(find ...)"
7 голосов
/ 25 февраля 2011

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

Сделать скрипт исполняемым

chmod +x lastline.sh

Использовать find:

find . -name "*.txt" -exec ./lastline.sh {} \;
4 голосов
/ 10 августа 2017

Благодаря Камило Мартину я смог ответить на связанный вопрос:

То, что я хотел сделать, было

find ... -exec zcat {} | wc -l \;

, который не работал. Тем не менее,

find ... | while read -r file; do echo "$file: `zcat $file | wc -l`"; done

работает, так что спасибо!

4 голосов
/ 19 октября 2011

1-й ответ Дениса - это решение проблемы.Но на самом деле это больше не находка с несколькими командами только в одном exec, как предполагает заголовок.Чтобы ответить на один exec несколькими командами, нам нужно искать что-то еще для разрешения.Вот пример:

Сохраните последние 10000 строк .log файлов, которые были изменены за последние 7 дней, используя 1 команду exec, используя несколько {} ссылок

1), посмотрите, что команда будетсделать, на каких файлах:

find / -name "*.log" -a -type f -a -mtime -7 -exec sh -c "echo tail -10000 {} \> fictmp; echo cat fictmp \> {} " \;

2) сделать это: (обратите внимание, больше не нужно "\>", а только ">")

find / -name "*.log" -a -type f -a -mtime -7 -exec sh -c "tail -10000 {} > fictmp; cat fictmp > {} ; rm fictmp" \;

1 голос
/ 22 июля 2016

следует использовать xargs:)

find *.txt -type f -exec tail -1 {} \; | xargs -ICONSTANT echo $(pwd),CONSTANT

еще один (работает на osx)

find *.txt -type f -exec echo ,$(PWD) {} + -exec tail -1 {} + | tr ' ' '/'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...