У меня есть вопрос о поиске и замене в 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