Как работает автоформат команды join?

Вопрос или проблема

Вот пример:

$ cat file1
hello
there
$ cat file2
some,very,long,line,hello,csv
some,very,long,line,nope,csv
$ join -t, -1 1 -2 5 file1 file2
hello,some,very,long,line,csv

Это работает как задокументировано: объединенное поле вытаскивается налево, остальные поля выводятся.

Но я хочу сохранить порядок столбцов CSV (file2). Я могу вывести CSV в неизменном виде с помощью этой команды, которая явно перечисляет номера полей CSV:

join -t, -1 1 -2 5 -o $(head -n1 file2 | awk -F, '{print NF}' | xargs seq | sed 's/^/2./' | paste -d, -s) file1 file2

И это выводит:

some,very,long,line,hello,csv

Я думал, что именно для этого в join есть формат auto. Вот что говорит страница man для join о -o FORMAT:

Если FORMAT — это ключевое слово ‘auto’, то первая строка каждого файла определяет количество полей, выводимых для каждой строки.

Тем не менее, я не знаю, что это означает или как мне следует использовать формат auto.

Я пробовал это, но не получил ничего другого, чем раньше:

$ join -t, -1 1 -2 5 -o auto file1 file2
hello,some,very,long,line,csv

Наивная интерпретация была бы таковой: я должен перечислить необходимые поля как первую строку каждого файла, но это тоже неверно.

Итак, мой вопрос: для чего нужен auto, и как мне его использовать? Могу ли я использовать его, чтобы сохранить порядок столбцов входного CSV?

Лично я считаю, что вывод по умолчанию от join такой, как я и ожидал (сначала поля объединения, затем остальные поля из file1, затем остальные поля из file2). Я не знаю, какой другой вывод имел бы смысл в общем случае объединения 2 файлов по ключевым полям (оставить ключевые поля в позиции file1, в позиции file2 или что-то еще? Будут ли неключевые поля, объединенные из обоих файлов, в алфавитном порядке или что-то еще?) и всегда есть -o, если вы предпочитаете какой-то другой формат, отличающийся от стандартного.

Относительно того, что означает -o auto, как вы привели:

Если FORMAT — это ключевое слово ‘auto’, то первая строка каждого файла определяет количество полей, выводимых для каждой строки.

Таким образом, если первая строка второго файла содержала 6 полей, а вторая строка 9 полей, то 6 полей этого файла будут напечатаны для каждой выходной строки, например:

$ cat file3
some,very,long,line,hello,csv
other,kina,long,line,hello,csv,jpeg,pdf,foobar
some,very,long,line,nope,csv

без -o auto:

$ join -t, -1 1 -2 5 file1 file3
hello,some,very,long,line,csv
hello,other,kina,long,line,csv,jpeg,pdf,foobar

в сравнении с -o auto:

$ join -t, -1 1 -2 5 -o auto file1 file3
hello,some,very,long,line,csv
hello,other,kina,long,line,csv

Сказав это, join все равно не был бы самым очевидным выбором для того, что вы пытаетесь сделать (вывести строки из file2, которые имеют значение ключа, хранящееся в file1). Например, используя любой awk в любой оболочке на всех системах Unix, это было бы просто:

$ awk -F, 'NR==FNR{k[$1]; next} $5 in k' file1 file2
some,very,long,line,hello,csv

$ awk -F, 'NR==FNR{k[$1]; next} $5 in k' file1 file3
some,very,long,line,hello,csv
other,kina,long,line,hello,csv,jpeg,pdf,foobar

Ответ или решение

Команда join в Unix/Linux предназначена для объединения строк из двух файлов на основе общих ключевых полей. При использовании опции формата -o, вы можете настраивать, какие поля включать в вывод. Опция -o auto имеет свои особенности, которые необходимо правильно интерпретировать для достижения желаемого результата.

Как работает автоформат -o auto

При использовании ключевого слова auto для опции -o, команда join будет использовать количество полей, определяемое первой строкой в каждом из файлов. Это означает, что join будет подстраивать вывод в зависимости от структуры этих строк.

Пример использования

Рассмотрим два файла:

Файл file1:

hello
there

Файл file2:

some,very,long,line,hello,csv
some,very,long,line,nope,csv

Если выполнить команду:

join -t, -1 1 -2 5 -o auto file1 file2

Вывод будет:

hello,some,very,long,line,csv

Результаты команды с -o auto

В данном случае, join выводит первое ключевое поле из file1 (содержимое hello), затем оно добавляет все соответствующие поля из file2, определяемые в порядке, в котором они указаны. Однако, если вам нужно сохранить порядок полей из file2 в выводе, используйте явное указание полей, как в вашем примере с использованием awk.

Как обеспечить нужный порядок колонок

Для достижения желаемого вывода с сохранением порядка колонок из file2, вы можете воспользоваться командой awk, как уже указано в вашем примере:

awk -F, 'NR==FNR{k[$1]; next} $5 in k' file1 file2

Эта команда позволяет находить строки из file2, которые содержат ключи из file1, сохраняя оригинальный порядок полей в выходных данных.

Заключение

Таким образом, использование -o auto может быть не совсем интуитивным, поскольку оно работает на основе количества полей в первой строке файлов. Если ваша задача заключается в сохранении оригинального порядка полей из одного из файлов, то прямое указание необходимых полей с помощью -o или использование awk будет более подходящим решением. Это даст вам возможность четко управлять форматом выводимых данных в соответствии с вашими требованиями.

Оцените материал
Добавить комментарий

Капча загружается...