Я новичок в awk и shell, интересно, как мне объединить 2 файла со строкой, которые имеют одинаковую запись, используя shell/awk? file1 и file2 могут иметь разный порядок для Name. Я хочу объединить только строки, которые имеют одинаковую запись. Пожалуйста, помогите.
file1.txt
Mary 68
Tom 50
Jason 45
Lu 66
file2.txt
Jason 37
Tom 26
Mary 74
Tina 80
mergefile.txt
Marry 68 74
Tom 50 26
Jason 45 37
Я попробовал awk, но для запуска скрипта требуется некоторое время. Интересно, есть ли более быстрая и простая реализация.
cat file1.txt | while read line
do
score1=$( echo $line | awk '{print $2}');
name1=$( echo $line | awk '{print $1}');
cat file2.txt | while read l
do
score2=$( echo $l | awk '{print $2}');
name2=$( echo $l | awk '{print $1}');
if [[ $name1 == $name2 ]]
then
echo "$name1 $score1 $score2" >> mergefile
break
fi
done
done
решение1
Если вы хотите использовать awk:
$ awk 'NR==FNR {a[$1] = $2; next} $1 in a {print $1, $2, a[$1]}' file2.txt file1.txt
Mary 68 74
Tom 50 26
Jason 45 37
Сортировка не требуется, вывод будет в порядке, указанном вторым файлом.
Объяснение:
NR==FNR
это канонический способ выбора записей из первого поименованного файла{a[$1] = $2; next}
заполнить массив ключами из первого поля и значениями из второго$1 in a
если первое поле уже было замечено в первом файле; тогда{print $1, $2, a[$1]}
распечатать ключ и значение из второго файла и значение из первого
решение2
Это звучит как работа дляjoin
, оператор реляционной базы данных
join <(sort file1.txt) <(sort file2.txt)
Тесты
$ cat file1.txt
Mary 68
Tom 50
Jason 45
Lu 66
$ cat file2.txt
Jason 37
Tom 26
Mary 74
Tina 80
$ join <(sort file1.txt) <(sort file2.txt)
Jason 45 37
Mary 68 74
Tom 50 26
join
стандартный инструмент, указанный в POSIX.
На странице руководства join
указано:
The files file1 and file2 shall be ordered in the collating sequence of sort -b on the fields on which they shall be joined, by default the first in each line. All selected output shall be written in the same collating sequence.