Как перенаправить вывод xargs при использовании sed

#linux #redirect #sed #xargs

#linux #перенаправление #sed #xargs

Вопрос:

После перехода на более совершенную систему управления я хочу удалить все избыточные журналы в верхней части каждого из наших исходных файлов. В Notepad я смог добиться результата, используя «заменить в файлах» и заменив совпадения на A(//.*n) пустые. Однако в Linux мне не повезло, и мне нужно прибегнуть к «xargs» и «sed».

Выражение sed, которое я использую, является:

sed '1,/^[^/]/{/^[^/]/b; d}'

Конечно, некрасиво, но, похоже, это работает.

Проблема, с которой я сталкиваюсь, заключается в том, что когда я пытаюсь запустить это через «xargs», чтобы передать ему все исходные файлы в нашей системе, я не могу перенаправить вывод на «удаленные» файлы, которые я затем намереваюсь скопировать поверх оригиналов.

Я хочу что-то в строке:

find . -name "*.com" -type f -print0 | xargs -0 -I file sed '1,/^[^/]/{/^[^/]/b; d}' "file" > "file.stripped"

Однако у меня возникают проблемы с передачей «>» в принимающую среду (оболочку), поскольку я уже использую слишком много кавычек. Я перепробовал все способы экранирования и оболочки «оболочки», но я просто не могу заставить его играть в мяч.

Кто-нибудь хочет указать мне правильное направление?

Спасибо, Сларти.

Комментарии:

1. Поддерживает ли ваша реализация sed -i эту опцию?

2. Есть, да, это так. Это делает жизнь намного проще. Я попробую и вернусь к вам 😉

3. Почему вы должны использовать опцию -exec в find. Что-то похожее на это, find . -name "*.com" -type f -print0 -exec sed '1,/^[^/]/{/^[^/]/b; d}' {} > "file.stripped" ;

4. Я попытался использовать опцию find «-exec», но также не смог заставить ее работать. Как бы то ни было, мне потребовалось так много времени, чтобы сформулировать вопрос с помощью моего телефона, что офис резко закрылся, и мне пришлось уйти, прежде чем пытаться выполнить какое-либо из этих предложений, но я полагаю, что ваше предложение либо добавит все в файл, буквально называемый «file.stripped», либо постоянно перезаписывает один и тот же файл любым текущимв то время была версия pc «{}». Обратите внимание, что замена «file.stripped» на «{}.stripped» также не работает, он просто создает файл с именем «{}.stripped».

Ответ №1:

Я сделал аналогичный сценарий с более простым выражением sed просто в качестве примера, посмотрите, работает ли он для вас:

Я создал 3 файла со строкой «abcd» внутри каждого:

 # ls -l
total 12
-rw-r--r-- 1 root root 5 Oct  6 09:05 test.aaaaa.com
-rw-r--r-- 1 root root 5 Oct  6 09:05 test2.aaaaa.com
-rw-r--r-- 1 root root 5 Oct  6 09:05 test3.aaaaa.com
# cat test*
abcd
abcd
abcd
  

Запуск команды find, как вы показали, с использованием опции -exec вместо xargs и замена выражения sed на глупое, которое просто заменяет каждое «a» на «b» и параметр -i, который записывает непосредственно во входной файл:

 # find . -name "*.com" -type f -print0 -exec sed -i 's/a/b/g' {} ;
./test2.aaaaa.com./test3.aaaaa.com./test.aaaaa.com
# cat test*
bbcd
bbcd
bbcd
  

В вашем случае это должно выглядеть так:

 # find . -name "*.com" -type f -print0 -exec sed -i '1,/^[^/]/{/^[^/]/b; d}' {} ;
  

Комментарии:

1. Спасибо. Это действительно сработало отлично. Из полноты, однако, есть идеи, как можно перенаправить вывод?

2. Этого нельзя достичь с помощью опции xargs -I, потому что после знака «>», используемого для перенаправления вывода, он понимает, что он больше не является частью аргументов команды, поэтому он не заменяет «file.stripped» на фактическое имя файла, которое вам дает «find», и в итоге создаетбуквальный файл «file.stripped». Для достижения этой цели вы могли бы написать скрипт, используя команду «for» в сочетании с «find» и «xargs», но это не самый умный и не самый простой способ сделать это. Кроме того, не забудьте поддержать мой ответ. 😉 Приветствия!