Intereting Posts
Персональная доска чертежей Исправить слишком длинную цепочку хеш-маршрутов без перезагрузки Недоступное запоминающее устройство USB (устройство Brick Garmin) Как изменить использование детоксикации по умолчанию, поэтому он просто не заменяет пробелы символами подчеркивания Можно ли использовать трубку вместо exec in – find / -name ".txt" -exec cp {} / junk \; vsftpd – ftp пользователь не может создавать папки Сортировка файла на основе 1 колонки Как посмотреть, какие порты открыты на определенном брандмауэре Объяснение% директив в find -printf Добавление почтовых ящиков псевдонимов с помощью Postfix Как принудительно использовать SMTP-серверы в Alpine? Ищете внешнюю команду, которая может делать то же самое, что и echo Не удалось перенаправить stdout / stderr в файл журнала Могу ли я размораживать bash или vim, когда сеанс SSH зависает от таймаута? Почему большинство приложений пытаются использовать OSS, если присутствует / dev / dsp?

Добавление другого суффикса в конец строки

У меня есть текстовый файл, который содержит следующее:

John Jack Jerry 

У меня есть другой текстовый файл:

 2017 2015 2018 

И я хочу сделать так:

 John2017 John2015 John2018 Jack2017 Jack2015 Jack2018 Jerry2017 Jerry2015 Jerry2018 

Как я могу это сделать?

Предполагая, что файлы невелики, может быть целесообразно прочитать их в массивы (с bash или ksh93 ):

 names=( $( <names.txt ) ) years=( $( <years.txt ) ) 

Затем вы можете построить двойной цикл, который объединяет каждое имя с каждым годом:

 for n in "${names[@]}"; do for y in "${years[@]}"; do printf '%s%s\n' "$n" "$y" done done 

Если years.txt мал, но names.txt большой:

 years=( $( <years.txt ) ) while read n; do for y in "${years[@]}"; do printf '%s%s\n' "$n" "$y" done done <names.txt 

Результат:

 John2017 John2015 John2018 Jack2017 Jack2015 Jack2018 Jerry2017 Jerry2015 Jerry2018 

Обработка файлов в виде файлов с одним столбцом, без заголовков, CSV:

 $ csvsql -H --query "SELECT * FROM names CROSS JOIN years" names.txt years.txt | sed -e '1d' -e 's/,//' 

Это выполняет операцию реляционного перекрестного соединения по данным в двух таблицах, а затем продолжает csvsql первую строку вывода вместе со всеми запятыми ( csvsql создает правильно отформатированный CSV с линией заголовка и значениями, разделенными запятыми).

csvsql является частью csvkit .

Решение, которое @ Kusalananda предоставило, превосходит его. Я предоставил его, не задумываясь о том, что $(cat ...) делает с точки зрения использования памяти. Я оставлю его здесь для справки – он будет работать и не страшен, если файлы маленькие.

 #!/bin/bash for name in $(cat names); do for year in $(cat years); do echo "${name}${year}" done done 
 $ join -j2 -t : names year | tr -d : 
  • соединить не существующее поле и удалить разделители выходных полей.

Поле 2 пусто и равно для всего элемента в names и year поэтому join объединяет каждое имя с годами: он фактически вычисляет декартово произведение.