1

У меня есть вопрос о поиске и замене в Debian. У меня есть два файла. Один с:

a:b
c:d
e:f

а другой с:

 e
 c
 a`

Во втором файле я хочу заменить a на b , c на d , e на f . Как я могу это сделать?

2 ответа2

1
$ 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 напечатать строку.

Замена файла2

Чтобы заменить 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 . Однако под поверхностью то, что делает эта опция, именно то, что делает команда выше.

1

Немного сложнее:

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .