Вопрос: перенаправление аргументов xargs


Это кажется тривиальной проблемой, но решение ускользает от меня так осторожно.

Я хочу очистить много текстовых файлов; лог-файлы. Причина? Сохранить на диске.

С одним текстовым файлом это так же тривиально, как echo '' > path/to/file.txt

Однако файлов много. Я прибегал к использованию find а также xargs, Но я не знаю, как обойти "перенаправление ввода",

я пытался find . -name <regex> | xargs -I target echo '' > target а также echo '' > { find . -name <regex> | xargs -I target target }; никто не работал

Я не очень разбираюсь в сценариях оболочки, и любая помощь приветствуется.

Благодарю.


4
2017-07-26 05:01


Источник




Ответы:


То, что вы сделали в обоих примерах, > где текущий оболочка может его увидеть, поэтому перенаправление выполняется только один раз, прежде чем команды find и xargs будут запущены. Это твоя первая проблема.

Вторая проблема заключается в том, что если вы укажете > так что он прошел до xargs, он все равно не будет работать, потому что xargs не передает вашу команду через оболочку, если вы ее не попросите.

Ваша третья проблема заключается в том, что если вы скажете xargs использовать оболочку для запуска команды, оболочка сделает неправильную вещь, если в каких-либо именах файлов есть забавные символы. (Также xargs делает неправильную вещь с забавными персонажами, но это исправляется с -0.)

Другие проблемы, которые вам пока могут не волновать, включают:

  • эхо '' не создает пустой файл, а файл, содержащий новую строку.
  • -name опция принимает glob, а не регулярное выражение.
  • вы можете добавить -type f на всякий случай, если любые каталоги соответствуют glob.

Вот частично исправленная версия команды:

find . -name '*thisisaglob*' -type f -print0 |
xargs -0 -I target sh -c ': > target'

Это устраняет большинство проблем, о которых я говорил. Тем не менее остается проблема оболочки, неверно интерпретирующая имя файла, содержащее метасимволы оболочки. Чтобы исправить это, вы должны указать имя файла для оболочки как параметр, а не как часть -c команда. Это будет выглядеть так:

find . -name '*thisisaglob*' -type f -print0 |
xargs -0 -I target sh -c ': > "$1"' fnord target

«Fnord» является заполнителем. Это становится $0 которые нам не нужны.

Теперь, достигнув цели безопасного использования xargs и перенаправления вместе, я покажу вам, как достичь своей цели, используя ни один из них.

find . -name '*thisisaglob*' -type f -exec truncate -s 0 '{}' +

Это требует truncate команда, которая является частью GNU coreutils, а не стандартной утилитой unix, поэтому она менее переносима, но гораздо легче читать, не так ли?


9
2017-07-26 05:29



Даже если это не ответ, это очень информативно. Однако это сработало. К сожалению, я могу только перевернуть один раз. Благодаря!! - iGbanam


Хотя ответ Алана Карри является тщательным, точным и очень хорошо осведомленным, у меня есть один вопрос. Почему вы хотите, чтобы файлы продолжали существовать, даже пустые?

Моя естественная рекомендация:

find . -name <glob> -print0 | xargs -0 rm

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

find . -name <glob> -print0 | tee /tmp/filelist | xargs -0 rm
cat /tmp/filelist | xargs -0 touch

Если вы просто хотели сжать файлы (например, если они были в основном избыточной / повторяющейся информацией, но вы хотели сэкономить место а также сохраните файлы), вы можете попробовать:

find . -name <glob> -print0 | xargs -0 tar -xzf /tmp/logfiles.tgz

2
2017-07-26 05:43



Это рельсовые приложения. Я бы предпочел хранить файлы, чтобы в рамках фреймворка было известно, где разместить журналы. - iGbanam


Если у вас есть GNU Parallel http://www.gnu.org/software/parallel/ вы можете сделать это:

find . -name '*thisisaglob*' -type f | parallel '>'

Вы можете установить GNU Parallel, просто:

wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel
cp parallel sem

Смотрите видеоролики для GNU. Параллельно узнайте больше: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1


0
2017-07-30 20:08