Подтвердить что ты не робот

Как выполнить несколько команд после xargs -0?

find . -name "filename including space" -print0 | xargs -0 ls -aldF > log.txt
find . -name "filename including space" -print0 | xargs -0 rm -rdf

Можно ли объединить эти две команды в одну так, чтобы вместо 2?

было выполнено только 1 find?

Я знаю, что для xargs -I могут быть способы сделать это, что может привести к ошибкам при продолжении имен файлов, включая пробелы. Любые рекомендации очень ценятся.

4b9b3361

Ответ 1

Если вам просто нужно избегать find несколько раз, вы можете сделать tee сразу после find, сохранив вывод find в файл, а затем выполнив строки как:

find . -name "filename including space" -print0 | tee my_teed_file | xargs -0 ls -aldF > log.txt
cat my_teed_file | xargs -0 rm -rdf 

Другой способ выполнить эту же задачу (если это действительно так, чего вы хотите достичь) - сохранить вывод find в переменной (предположим, что это не ТБ данных):

founddata=`find . -name "filename including space" -print0`
echo "$founddata" | xargs -0 ls -aldF > log.txt
echo "$founddata" | xargs -0 rm -rdf

Ответ 2

find . -name "filename including space" -print0 | 
  xargs -0 -I '{}' sh -c 'ls -aldF {} >> log.txt; rm -rdf {}'

Ответ 3

Я считаю, что теперь все эти ответы дали правильные пути решения этой проблемы. И я попробовал 2 решения Джонатана и способ Гленна, все из которых отлично поработали на моей Mac OS X. Метод mouviciel не работал на моей ОС, возможно, из-за некоторых причин конфигурации. И я думаю, что это похоже на второй метод Джонатана (возможно, я ошибаюсь).

Как упоминалось в комментариях к методу Гленна, требуется небольшая настройка. Итак, вот команда, которую я пробовал, которая отлично работала FYI:

find . -name "filename including space" -print0 | 
xargs -0 -I '{}' sh -c 'ls -aldF {} | tee -a log.txt ; rm -rdf {}'

Или лучше, как предложил Гленн:

find . -name "filename including space" -print0 | 
xargs -0 -I '{}' sh -c 'ls -aldF {} >> log.txt ; rm -rdf {}'

Ответ 4

Пока у вас нет новой строки в ваших именах файлов, вам не нужно -print0 для GNU Parallel:

find . -name "My brother 12\" records" | parallel ls {}\; rm -rdf {} >log.txt

Смотрите видеоролик, чтобы узнать больше: http://www.youtube.com/watch?v=OpaiGYxkSuQ

Ответ 5

Просто вариация подхода xargs без этих ужасных -print0 и xargs -0, вот как я это сделаю:

ls -1 *.txt  | xargs --delimiter "\n" --max-args 1 --replace={} sh -c 'cat {}; echo "\n"'

Сноска:

  • Да, я знаю, что новые строки могут появляться в именах файлов, но кто в здравом уме будет это делать
  • Есть короткие варианты для xargs, но для понимания читателем я использовал длинные.
  • Я бы использовал ls -1, когда мне нужно нерекурсивное поведение, а не find -maxdepth 1 -iname "*.txt", которое немного более подробное.

Ответ 6

Вы можете выполнить несколько команд после find с помощью for вместо xargs:

IFS=$'\n'
for F in `find . -name "filename including space"`
do
    ls -aldF $F > log.txt
    rm -rdf $F
done

IFS определяет внутренний разделитель полей, который по умолчанию равен <space> < tab <newline> . Если ваши имена файлов могут содержать пробелы, лучше переопределить их, как указано выше.

Ответ 7

Я опаздываю на вечеринку, но есть еще одно решение, которое здесь не было описано: пользовательские функции. Наложение нескольких инструкций на одну строку громоздко и может быть трудно читать/поддерживать. Цикл for выше позволяет избежать этого, но есть вероятность превышения длины командной строки.

Здесь другой способ (непроверенный).

function processFiles {
  ls -aldF "[email protected]"
  rm -rdf "[email protected]"
}
export -f processFiles

find . -name "filename including space"` -print0 \
  | xargs -0 bash -c processFiles dummyArg > log.txt

Это довольно просто, за исключением "dummyArg", который дал мне много горя. При запуске bash таким образом аргументы считываются в

"$0" "$1" "$2"  ....

вместо ожидаемого

"$1" "$2" "$3"    ....

Так как processFiles {} ожидает, что первый аргумент будет " $1", мы должны вставить фиктивное значение в " $0" .

Footnontes:

  • Я использую некоторые элементы синтаксиса bash (например, export -f "), но я считаю, что это будет адаптироваться к другим оболочкам.
  • В первый раз, когда я попробовал это, я не добавил фиктивный аргумент. Вместо этого я добавил " $0" в строки аргументов внутри моей функции (например, ls -aldf "$ 0" "$ @" ). Плохая идея. Помимо стилистических проблем, он прерывается, когда команда find ничего не возвращает. В этом случае $0 устанавливается на "bash", используя фиктивный аргумент, вместо этого избегает всего этого.

Ответ 8

Другое решение:

find . -name "filename including space" -print0 \
| xargs -0 -I FOUND echo "$(ls -aldF FOUND > log.txt ; rm -rdf FOUND)"