File1.txt
item1 carA
item2 carB
item3 carC
item4 platD
item5 carE
File2.txt
carA platA
carB platB
carC platC
carE platE
Требуемый вывод:
item1 platA
item2 platB
item3 platC
item4 platD
item5 platE
Как я могу это сделать?
Я знаю, что вы сказали awk, но для этой цели есть команда join ...
{
join -o 1.1,2.2 -1 2 -2 1 <(sort -k 2 File1.txt) <(sort -k 1 File2.txt)
join -v 1 -o 1.1,1.2 -1 2 -2 1 <(sort -k 2 File1.txt) <(sort -k 1 File2.txt)
} | sort -k 1
Этого было бы достаточно с первой командой join, если бы это wasn 't для этой строки:
item4 platD
Команда в основном говорит: join на основе второго столбца первого файла (-1 2) и первого столбца второго файла (-2 1) , и выведите первый столбец первого файла и второй столбец второго файла (-o 1.1,2.2). Это только показывает линии, которые соединяются. Вторая команда соединения говорит почти то же самое, но говорит, что она показывает строки из первого файла, который не может быть спарен (-v 1), и выводит первый столбец первого файла, а второй столбец первого файла (-o 1.1,1.2). Затем мы сортируем результат как комбинированных. sort -k 1 означает сортировку на основе первого столбца, а sort -k 2 означает сортировку на основе второго. Важно сортировать файлы на основе столбца объединения, прежде чем передавать их в join.
Теперь я дважды сортировал сортировку, потому что мне не нравятся файлы моих файлов, если я могу помочь Это. Однако, как сказал Дэвид Фостер, в зависимости от размера файлов, вы можете отсортировать файлы и сначала сохранить их, чтобы не ждать, чтобы сортировать их дважды. Чтобы дать представление о размерах, пришло время сортировать 1 миллион и 10 миллионов строк на моем компьютере:
$ ruby -e '(1..1000000).each {|i| puts "item#{i} plat#{i}"}' | shuf > 1million.txt
$ ruby -e '(1..10000000).each {|i| puts "item#{i} plat#{i}"}' | shuf > 10million.txt
$ head 10million.txt
item530284 plat530284
item7946579 plat7946579
item1521735 plat1521735
item9762844 plat9762844
item2289811 plat2289811
item6878181 plat6878181
item7957075 plat7957075
item2527811 plat2527811
item5940907 plat5940907
item3289494 plat3289494
$ TIMEFORMAT=%E
$ time sort 1million.txt >/dev/null
1.547
$ time sort 10million.txt >/dev/null
19.187
Это 1,5 секунды для 1 миллиона строк и 19 секунд для 10 миллионов строк .
Следующий ответ основан на аналогичном Q & amp; A в SO с некоторыми соответствующими изменениями:
$ awk 'FNR==NR {dict[$1]=$2; next} {$2=($2 in dict) ? dict[$2] : $2}1' file2.txt file1.txt
item1 platA
item2 platB
item3 platC
item4 platD
item5 platE
Идея состоит в создании хэш-карты с индексом и использовании ее в качестве словаря. [ ! d2]
Для второго вопроса, который вы задали в своем комментарии (что должно быть изменено, если второй столбец file1.txt будет шестым столбцом):
Если входной файл будет как file1b.txt:
item1 A5 B C D carA
item2 A4 1 2 3 carB
item3 A3 2 3 4 carC
item4 A2 4 5 6 platD
item5 A1 7 8 9 carE
Следующая команда сделает это:
$ awk 'FNR==NR {dict[$1]=$2; next} {$2=($6 in dict) ? dict[$6] : $6;$3="";$4="";$5="";$6=""}1' file2.txt file1b.txt
item1 platA
item2 platB
item3 platC
item4 platD
item5 platE
Я знаю, что вы сказали awk, но для этой цели есть команда join ...
{
join -o 1.1,2.2 -1 2 -2 1 <(sort -k 2 File1.txt) <(sort -k 1 File2.txt)
join -v 1 -o 1.1,1.2 -1 2 -2 1 <(sort -k 2 File1.txt) <(sort -k 1 File2.txt)
} | sort -k 1
Этого было бы достаточно с первой командой join, если бы это wasn 't для этой строки:
item4 platD
Команда в основном говорит: join на основе второго столбца первого файла (-1 2) и первого столбца второго файла (-2 1) , и выведите первый столбец первого файла и второй столбец второго файла (-o 1.1,2.2). Это только показывает линии, которые соединяются. Вторая команда соединения говорит почти то же самое, но говорит, что она показывает строки из первого файла, который не может быть спарен (-v 1), и выводит первый столбец первого файла, а второй столбец первого файла (-o 1.1,1.2). Затем мы сортируем результат как комбинированных. sort -k 1 означает сортировку на основе первого столбца, а sort -k 2 означает сортировку на основе второго. Важно сортировать файлы на основе столбца объединения, прежде чем передавать их в join.
Теперь я дважды сортировал сортировку, потому что мне не нравятся файлы моих файлов, если я могу помочь Это. Однако, как сказал Дэвид Фостер, в зависимости от размера файлов, вы можете отсортировать файлы и сначала сохранить их, чтобы не ждать, чтобы сортировать их дважды. Чтобы дать представление о размерах, пришло время сортировать 1 миллион и 10 миллионов строк на моем компьютере:
$ ruby -e '(1..1000000).each {|i| puts "item#{i} plat#{i}"}' | shuf > 1million.txt
$ ruby -e '(1..10000000).each {|i| puts "item#{i} plat#{i}"}' | shuf > 10million.txt
$ head 10million.txt
item530284 plat530284
item7946579 plat7946579
item1521735 plat1521735
item9762844 plat9762844
item2289811 plat2289811
item6878181 plat6878181
item7957075 plat7957075
item2527811 plat2527811
item5940907 plat5940907
item3289494 plat3289494
$ TIMEFORMAT=%E
$ time sort 1million.txt >/dev/null
1.547
$ time sort 10million.txt >/dev/null
19.187
Это 1,5 секунды для 1 миллиона строк и 19 секунд для 10 миллионов строк .
Следующий ответ основан на аналогичном Q & amp; A в SO с некоторыми соответствующими изменениями:
$ awk 'FNR==NR {dict[$1]=$2; next} {$2=($2 in dict) ? dict[$2] : $2}1' file2.txt file1.txt
item1 platA
item2 platB
item3 platC
item4 platD
item5 platE
Идея состоит в создании хэш-карты с индексом и использовании ее в качестве словаря. [ ! d2]
Для второго вопроса, который вы задали в своем комментарии (что должно быть изменено, если второй столбец file1.txt будет шестым столбцом):
Если входной файл будет как file1b.txt:
item1 A5 B C D carA
item2 A4 1 2 3 carB
item3 A3 2 3 4 carC
item4 A2 4 5 6 platD
item5 A1 7 8 9 carE
Следующая команда сделает это:
$ awk 'FNR==NR {dict[$1]=$2; next} {$2=($6 in dict) ? dict[$6] : $6;$3="";$4="";$5="";$6=""}1' file2.txt file1b.txt
item1 platA
item2 platB
item3 platC
item4 platD
item5 platE