Ответ 1
Это может сработать для вас (GNU sed):
sed -i -e '/bar/{w file2' -e 'd}' file1
Альтернатива:
sed -i -e '/bar/w file2' -e '//d' file1
Я хочу переместить строки, соответствующие определенному шаблону, из файла1 в файл2. Аналогично операции вырезания и вставки из одного файла в другой в windows
Пример
скажем, я хочу вырезать все строки, контактирующие с bar
из файла1, и вставить его во вновь созданный файл2
Input:
файл1
bla foo bla
bla bar bla
bla aaa bla
bla bar bla
bla foo bla
Желаемый результат после обработки:
файл1
bla foo bla
bla aaa bla
bla foo bla
файл2
bla bar bla
bla bar bla
Что я пробовал
grep
создает желаемый файл2, но не изменяет file1
grep 'bar' file1 > file2
sed -i
изменяет желаемый файл1, но не создает файл2
sed -i '/bar/d' file1
Если я выполняю обе команды один за другим, я получаю желаемый результат. Но здесь я ищу одиночную строку из любопытства и сделать script более кратким.
Ваша помощь будет оценена.
Это может сработать для вас (GNU sed):
sed -i -e '/bar/{w file2' -e 'd}' file1
Альтернатива:
sed -i -e '/bar/w file2' -e '//d' file1
Вы можете использовать perl и выбрать другой дескриптор файла, основанный на совпадении регулярного выражения при печати:
perl -i.bak -ne 'BEGIN { open $oh, q|>|, pop or die } { print { m/bar/ ? $oh : q|ARGVOUT| } $_ }' file1 file2
Это дает:
==> file1 <==
bla foo bla
bla aaa bla
bla foo bla
==> file2 <==
bla bar bla
bla bar bla
Этот awk
script выполнит трюк:
awk '{a[NR]=$0}END{for(i=1;i<=NR;i++)print a[i] > "file"(a[i]~/bar/?2:1)}' file1
Выходы:
$ cat file1
bla foo bla
bla aaa bla
bla foo bla
$ cat file2
bla bar bla
bla bar bla
Вы можете поместить &&
между двумя командами, чтобы сделать их одной строкой. Но это не будет более читаемым, поэтому я не рекомендую вам это делать.
Чтобы сделать то же самое в одной команде, вам понадобится что-то, что может редактировать файл на месте, удаляя ненужные строки и в то же время печатать эти строки до stdout
или stderr
, чтобы вы могли перенаправить его в другой файл.
Может быть, ed
может это сделать, но я не знаю, как это написать.
Я не думаю, что для этого есть еще один "стандартный" UNIX-инструмент.
Btw, вырезать и вставлять на самом деле имеет 3 шага:
Двухэтапная команда UNIX делает это без буфера обмена.
Мне нравятся другие ответы, но просто (очевидный) альтернативный подход на случай, если вы беспокоитесь о том, чтобы совершить ошибку в своем шаблоне и хотите облегчить откат:
grep 'bar' file1 > file2
grep -v 'bar' file1 > file3
Как только вы будете довольны своими результатами (подсказка: tee
вместо >
позволит вам увидеть, что нужно записать в ваши файлы):
mv file3 file1
Обычно я предпочитаю perl делать подстановку, как в приведенном выше ответе, но когда идиома регулярного выражения становится слишком сложной, и вы не слепо копируете и вставляете команды, которые вы не понимаете, вы не контролируете свои драгоценные данные.