сортировать файл B на основе столбца 3 файла A без изменения содержимого файла A

сортировать файл B на основе столбца 3 файла A без изменения содержимого файла A

У меня есть следующий файл:

cat fileA.txt

seattle    1991  west
atlanta    1993  west
turlock    1998  west
marysville 2004  south
newyork    2007  north
canada     2004  west

А второй файл выглядит так:

cat fileB.txt

popular
someWhatPopular
boring
popular
popular
popular

Я хотел бы получить следующий результат fileB.txt:

popular popular popular someWhatPopular boring popular

По сути, я пытаюсь отсортировать fileB.txtпо fileA.txtтретьему столбцу.

Я попробовал следующий код:

   #!/bin/bash
   sort -s -k3,3 fileA.txt fileB.txt

Но это не сработало. Есть предложения? Я вполне открыт для всего, что не требует хардкодинга. Bash/awk/sed и т. д.

решение1

Это проблема структуры данных, а не только Linux. Вам нужна общая запись (ключ) в обеих таблицах, чтобы связать их, как и в любой «базе данных», и хорошей практикой является сохранение уникального ключа в первом столбце любой таблицы данных. Затем вы можете сортировать и связывать, как душе угодно.

Взяв что-то вроде @glennjackman mapping, вы определяете ключ сопоставления как север, юг и т. д.

1 south somewhatPopular
2 west popular
3 north boring
4 east unexplored

в файле с именем file popularity. Изменить, fileAвключив уникальный ключ

1 seattle    1991  west
2 atlanta    1993  west
3 turlock    1998  west
4 marysville 2004  south
5 newyork    2007  north
6 canada     2004  west

затем вы можете манипулировать этими файлами, сопоставляя joinих с выбранным вами ключом (в вашем случае столбец 2 в popularityсопоставляется со столбцом 4 в fileA), но join для этого оба файла должны быть отсортированы по ключевому полю, поэтому

join -1 4 -2 2 <(sort -k4 fileA) <(sort -k2 popularity) | sort -k2 | awk '{print $6}'

popular
popular
popular
somewhatPopular
boring
popular

Это немного грубый подход, но он обеспечивает максимальную гибкость.

Разбейте указанную выше команду на каждом этапе, и вы увидите, что делает каждый шаг.

Редактировать: Объяснениеjoin -1 4 -2 2 # its in the man pages

Это говорит нам joinо том, что нужно посмотреть на 4-й столбец в таблице 1 (-1 4) и найти соответствующие значения во 2-м столбце таблицы 2 (-2 2).

joinзатем объединяет столбцы из двух таблиц в одну таблицу, но включает только ключевой столбец (север и т. д.) один раз. Посмотрите на вывод из

join -1 4 -2 2 <(sort -k4 fileA) <(sort -k2 popularity)

и это должно быть более ясно

Поскольку нам нужно было отсортировать таблицы данных для joinработы, мы затем

| sort -k2

объединенную таблицу, чтобы вернуть их в исходный порядок.

Нужный вам столбец — это столбец 6 в объединенной таблице, поэтому мы просто

| awk '{print $6}'

на стандартный вывод.

решение2

Вы можете попробовать pasteобъединить два файла «таблицы», передать вывод в sort, а затем cutоставить только четвертый столбец.

Непроверенная (сейчас это мобильный телефон) попытка будет выглядеть примерно так:

paste fileA fileB | sort -s -k3,3 | cut -f4

решение3

Вы можете получить алфавитное отображение с помощью

paste <(awk '{print $NF}' fileA.txt | sort -u) <(sort -u fileB.txt)
north   boring
south   popular
west    someWhatPopular

И затем желаемый вами вывод можно получить с помощью awk:

awk '
    NR==FNR {map[$1] = $2; next} 
    {print map[$NF]}
' <(paste <(awk '{print $NF}' fileA.txt | sort -u) <(sort -u fileB.txt)) fileA.txt
someWhatPopular
someWhatPopular
someWhatPopular
popular
boring
someWhatPopular

Связанный контент