Соединение строк в двух файлах в bash на основе значения

Вы можете установить любые версии из исходников. Загрузите исходный код для любых версий Unison, которые вы хотите , с этой страницы , скомпилируйте и установите их по одной. Затем после каждой установки заходите в установочный каталог (, возможно /usr/bin/), и копируйте только что установленный исполняемый файл unisonв unison-VERSIONNUMBERили что-то в этом роде. И затем вы можете запустить любую версию Unison, которую хотите, просто указав номер версии.

Если вы хотите избежать установки Unison из исходного кода и вместо этого устанавливать разные версии через менеджер пакетов, тогда ваш вопрос больше касается вашего менеджера пакетов, чем Unison.

0
25.02.2020, 01:12
2 ответа

Использование join, GNU sedиsort:

join -t '#'\
  <(sed 's/ (/#(/' file1 | sort)\
  <(sed -z 's/\n/#/g; s/##/\n/g; $ s/#$//' file2 | sort)\
  | sort -t'#' -nrk2.2\
  | sed '2,$ s/^/\n/g; s/#/ /; s/#/\n/g'

В этой команде неиспользуемый символ #используется как временный разделитель полей и токен новой строки.

Выход:

Jim (30)
some jim info here
some jim other info
more jim info

Adrian Lors (23)
some adrian info here
some adrian other info
more adrian info

John (20)
some john info here
some john other info
more john info

Подробно

Первый аргументjoin

$ sed 's/ (/#(/' file1 | sort
Adrian Lors#(23)
Jim#(30)
John#(20)

заменяет последний символ пробела в каждой строке разделителем соединения #и сортирует результат.


Второй аргумент вjoin:

$ sed -z 's/\n/#/g; s/##/\n/g; $ s/#$//' file2 | sort
Adrian Lors#some adrian info here#some adrian other info#more adrian info
Jim#some jim info here#some jim other info#more jim info
John#some john info here#some john other info#more john info
  • Используйте sed -zдля чтения файла, чтобы упростить замену новых строк.
  • Первые две подстановки используются для размещения текста для каждого имени в одной строке :Замените каждую новую строку на #и замените два ##обратно на одну новую строку.
  • Последняя подстановка удаляет #в конце файла (последнюю новую строку ).
  • Отсортируйте результат.

Объединенный и снова отсортированный результат выглядит так:

$ join -t '#'\
    <(sed 's/ (/#(/' file1 | sort)\
    <(sed -z 's/\n/#/g; s/##/\n/g; $ s/#$//' file2 | sort)\
    | sort -t'#' -nrk2.2
Jim#(30)#some jim info here#some jim other info#more jim info
Adrian Lors#(23)#some adrian info here#some adrian other info#more adrian info
John#(20)#some john info here#some john other info#more john info

Объединить обе подстановки процесса в первом поле и обратную числовую сортировку во втором поле, начиная с позиции 2.


Оставшаяся часть

... | sed '2,$ s/^/\n/g; s/#/ /; s/#/\n/g'

заменяет разделитель соединения и возвращает символы новой строки:

  • Добавить новую строку в начале каждой строки, начиная со строки 2 (пустые строки ).
  • Замените первые #в каждой строке символом пробела, а оставшиеся #замените символами новой строки.
0
28.04.2021, 23:22

Возможно, это то, что вы ищете:

$ cat tst.awk
NR==FNR {
    val = $NF
    gsub(/^[[:space:]]+|[[:space:]]+[^[:space:]]+[[:space:]]*$/,"")
    map[$0] = val;
    next
}
FNR==1 {
    FS = OFS = "\n"
    ORS = "\n\n"
    $0 = $0
}
{
    $1 = $1 " " map[$1]
    print
}

$ awk -f tst.awk file1 RS= file2
Jim (30)
some jim info here
some jim other info
more jim info

John (20)
some john info here
some john other info
more john info

Adrian Lors (23)
some adrian info here
some adrian other info
more adrian info
1
28.04.2021, 23:22

Теги

Похожие вопросы