У меня есть вопрос о поиске и замене в Debian. У меня есть два файла. Один с:
a:b
c:d
e:f
а другой с:
e
c
a`
Во втором файле я хочу заменить a
на b
, c
на d
, e
на f
.
Как я могу это сделать?
$ awk -F: 'FNR==NR{a[$1]=$2;next} {for (i in a)sub(i, a[i]);print}' file1 file2
f
d
b
-F:
Это говорит awk
разбивать поля на двоеточие.
FNR==NR{a[$1]=$2;next}
При чтении первого файла это говорит awk
создать словарь a
из переводов, которые мы хотим сделать.
for (i in a)sub(i, a[i])
При чтении второго файла, это говорит awk
заменять каждую запись, которую мы сохранили в нашем словаре a
.
print
После того, как мы сделали замены, это говорит awk
напечатать строку.
Чтобы заменить file2
новой версией:
awk -F: 'FNR==NR{a[$1]=$2;next} {for (i in a)sub(i, a[i]);print}' file1 file2 >tmp && mv tmp file2
В самых последних версиях awk
этого есть опция быстрого доступа: -i inplace
. Однако под поверхностью то, что делает эта опция, именно то, что делает команда выше.
Немного сложнее:
sed -f <(sed 's!\(.*\):\(.*\)!s/\1/\2/!' file1) file2
sed 's!\(.*\):\(.*\)!s/\1/\2/!' file1
читает первый файл и выводит:
s/a/b/
s/c/d/
s/e/f/
<(the_above)
запускает указанную выше команду с выводом во временный файл.sed -f <(…) file2
запускает sed
для file2
используя этот временный файл в качестве файла ввода (сценария).Чтобы отправить вывод обратно в file2
, добавьте опцию -i
:
sed -i -f <(sed 's!\(.*\):\(.*\)!s/\1/\2/!' file1) file2