У меня нет опыта работы с awk, sed, grep и т. д. Попытка сформулировать мой вопрос приводит к тому, что он кажется более запутанным, чем должен быть, поэтому я начну с примера того, чего я пытаюсь достичь.
input1
A B C D
A B C
A B C D E F
input2
v A
c B
c C
c D
v E
output
A B C D
v c c c
A B C
v c c
A B C D E F
v c c c v Ø
Итак, в основном у меня есть 2 входных файла.
input1
, где каждая строка имеет разное количество полей.
input2
, где каждая строка имеет 2 поля.
Мне нужен output
, где для каждой строки в input1
сначала выводится полная строка со всеми полями, затем для следующей строки output
, он будет искать содержимое каждого поля этой строки из input1
во втором поле input2
. Затем выведите первое поле этой строки из input2
, или Ø
, если это содержимое не найдено в input2
. Повторяйте это до последнего поля, выводя результаты в одну строку. Затем сделайте то же самое для каждой строки в input1
.
Поскольку я буду выполнять немного разные задачи, краткое объяснение того, что делает каждая часть команд, было бы весьма признательно. Заранее спасибо.
Кажется, это работает:
awk 'NR==FNR { code[$2]=$1 } NR!=FNR {print; for( i=0; i<=NF; i++) { printf( "%s ", code[$i] ) }; printf "\n" }' input2 input1
Блок NR==FNR
работает только с первым файлом, указанным (, в котором общее количество обработанных записей равно общему количеству на данный момент ), и заполняет массив, используемый для вывода позже.
Блок NR!=FNR
работает только с последующим файлом и сначала выводит заданную строку ввода, а затем проходит через нее и использует каждое значение в качестве нижнего индекса поиска в массиве, чтобы определить, следует ли выводить v
или c
.
После этого повторяющегося ряда выводится новая строка.
$ awk 'FNR == NR { a[$2] = $1; next }
{ print
line = (a[$1] ? a[$1] : "Ø")
for (i = 2; i <= NF; ++i) {
line = line OFS (a[$i] ? a[$i] : "Ø")
}
printf("%s\n", line)
}' input2 input1
A B C D
v c c c
A B C
v c c
A B C D E F
v c c c v Ø
То есть, если мы читаем из первого файла (input2
), заполните справочную таблицу символами, на которые следует заменить каждый символ.
При чтении второго файла(input1
)выведите входную строку, затем выполните цикл по полям и создайте строку с правильными символами из таблицы поиска. Если символ отсутствует в таблице поиска, вставьте Ø
.
Затем выведите собранную строку с завершающим символом новой строки.
Вы также можете превратить его в правильный скрипт:
#!/usr/bin/awk -f
FNR == NR { a[$2] = $1; next }
{ print
line = (a[$1] ? a[$1] : "Ø")
for (i = 2; i <= NF; ++i) {
line = line OFS (a[$i] ? a[$i] : "Ø")
}
printf("%s\n", line)
}
Затем сделайте его исполняемым(chmod +x script
)и запустите так:
$./script input2 input1
A B C D
v c c c
A B C
v c c
A B C D E F
v c c c v Ø