Манипуляции со строками в AWK - PullRequest
0 голосов
/ 13 февраля 2019

Я пытаюсь сопоставить данные из двух файлов и создать новый файл с результатами.

Файл 1 содержит данные, которые выглядят следующим образом:

19V17R1-wipedrive-2016.05.23-07.25PM-d0.pdf
19XPT32-wipedrive-2016.05.03-05.50AM-d0.pdf
19XPT32-wipedrive-2016.07.06-08.32PM-d0.pdf
1BC6062-wipedrive-2018.07.26-08.34AM-d0.pdf

Файл 2 содержит только первые 7 символов, например:

19V17R1
1BC6062

Окончательный файл должен выглядетьнапример:

19V17R1 19V17R1-wipedrive-2016.05.23-07.25PM-d0.pdf
1BC6062 1BC6062-wipedrive-2018.07.26-08.34AM-d0.pdf

Я могу сопоставить файлы, создав файл, содержащий только первые 7 символов, а затем выполнив:

awk 'FNR==NR{!a[$1]++;next}$0 in a' /RMAs.txt /sortedWipelogs.txt > matches.text

Что я не могу понять, так это каквыведите все имя файла во втором столбце.Спасибо.

Ответы [ 5 ]

0 голосов
/ 13 февраля 2019

Есть много способов сделать это.Уже есть ответ join.Вот grep one:

$ grep -F -f file2 file1
19V17R1-wipedrive-2016.05.23-07.25PM-d0.pdf
1BC6062-wipedrive-2018.07.26-08.34AM-d0.pdf

Но это также может соответствовать другим частям файла, но если вы уверены в формате.Это сделает это.Вам также не нужны первые столбцы, так как они совпадают!Если вы хотите первый столбец, вы можете сделать это просто так

$ grep -F -f file2 file1 | awk '{print substr($0,1,7), $0 }'
19V17R1 19V17R1-wipedrive-2016.05.23-07.25PM-d0.pdf
1BC6062 1BC6062-wipedrive-2018.07.26-08.34AM-d0.pdf

или просто

$ awk '(NR==FNR){a[$1];next}(substr($0,1,7) in a){ print substr($0,1,7), $0 }' file2 file1

или даже короче с - в качестве разделителя (только для file1чтобы избежать возможных проблем с пробелами в file2

$ awk '(NR==FNR){a[$1];next}($1 in a){ print $1, $0 }' file2 FS="-" file1
0 голосов
/ 13 февраля 2019

Использование Perl

perl -lne ' BEGIN { $x=join("|", map{chomp;$_} qx(cat mweb2.txt)) } s/^($x)/$1 $1/g and print '

со входами

$ cat mweb1.txt
19V17R1-wipedrive-2016.05.23-07.25PM-d0.pdf
19XPT32-wipedrive-2016.05.03-05.50AM-d0.pdf
19XPT32-wipedrive-2016.07.06-08.32PM-d0.pdf
1BC6062-wipedrive-2018.07.26-08.34AM-d0.pdf

$ cat mweb2.txt
19V17R1
1BC6062

$ perl -lne ' BEGIN { $x=join("|", map{chomp;$_} qx(cat mweb2.txt)) } s/^($x)/$1 $1/g and print ' mweb1.txt
19V17R1 19V17R1-wipedrive-2016.05.23-07.25PM-d0.pdf
1BC6062 1BC6062-wipedrive-2018.07.26-08.34AM-d0.pdf

$
0 голосов
/ 13 февраля 2019

Это так же просто, как создание следующего go.awk:

NR==FNR { lookup[substr($0,1,7)] = $0 }
NR!=FNR { print $0" "lookup[$0] }

Затем вы запускаете его с помощью:

awk -f go.awk file1.txt file2.txt

Первая команда выполняется для каждой строки в first входной файл, и он просто сохраняет всю строку в ассоциативном массиве, набранном на первых семи символах, для последующего поиска.

Вторая команда для каждого файла во втором и последующих входных файлах, выводит строку и соответствующую запись в ассоциативный массив.Вывод, который вы видите, является именно тем, о чем вы просили:

19V17R1 19V17R1-wipedrive-2016.05.23-07.25PM-d0.pdf
1BC6062 1BC6062-wipedrive-2018.07.26-08.34AM-d0.pdf

Теперь я предпочитаю , используя сценарии, поскольку это означает, что мне не нужно искать в своей истории произвольно сложные awk команды, но, если вы хотите, чтобы однострочник делал то же самое:

awk 'NR==FNR{lookup[substr($0,1,7)]=$0}NR!=FNR{print $0" "lookup[$0]}' file1.txt file2.txt
0 голосов
/ 13 февраля 2019

если оба файла отсортированы, как показано, то просто

$ join -t- file1 file2

19V17R1-wipedrive-2016.05.23-07.25PM-d0.pdf
1BC6062-wipedrive-2018.07.26-08.34AM-d0.pdf

для нужного формата вывода, это может быть проще, чем установка -o параметров join

$ join <(awk '{print substr($0,1,7) "\t" $0}' file1) file2

19V17R1 19V17R1-wipedrive-2016.05.23-07.25PM-d0.pdf
1BC6062 1BC6062-wipedrive-2018.07.26-08.34AM-d0.pdf
0 голосов
/ 13 февраля 2019

Не могли бы вы попробовать следующее.

awk 'FNR==NR{a[$0]=$0;next} a[$1]{print a[$1],$0}' Input_file2  FS="-" Input_file1

Объяснение: Добавление пояснения к вышеуказанному коду сейчас.

awk '
FNR==NR{                  ##Checking condition FNR==NR which will be true when first Input_file named file2 is being read.
  a[$0]=$0                ##Creating an array named a whose index is $0 and value is $0.
  next                    ##Using next will skip all further statements from here.
}                         ##Closing block for FNR==NR here.
a[$1]{                    ##Checking condition if a[$1] is NOT NULL then do following.
  print a[$1],$0          ##Printing value of array a whose index is $1 of current lie, along with the current line.
}' file2  FS="-" file1    ##Closing block and mentioning Input_file file2 name then setting FS="-" and mentioning Input_file name file1 here.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...