Сортировка файлов .dat по внутренним данным

Сортировка файлов .dat по внутренним данным

У меня есть несколько файлов .dat (переменных), в каждом из которых содержится два фрагмента информации: вес и рост, разделенные пробелом, как показано ниже, где First_Last — это имя:

18kg 1.2mв "First1_Last1.dat"

12kg 1.6mв "First2_Last2.dat" и т.д.

Мне нужно отсортировать их либо по первому, либо по второму значению в каждом. Я думаю, что мне нужно catобъединить все файлы, убрать единицы измерения с помощью cut(не уверен в этом), затем добавить имена файлов в качестве третьего столбца, используя pasteи, наконец, sort -k 1,1 temp.txtво временном файле, чтобы получить желаемый вывод, при этом все еще имея возможность отслеживать, из какого файла пришло каждое значение, потому что мне нужны связанные имена, чтобы открыть другой файл для каждого человека в правильном порядке после этого. Таким образом, мой выходной файл, который я бы использовал, выглядел бы примерно так:

12 1.6 First2_Last2.dat
18 1.2 First1_Last1.dat

Мне интересно, есть ли лучший способ сделать это, используя что-то встроенное или свойство типа файла .dat, которого мне не хватает. Или, может быть, используя awk?

решение1

Вы можете использовать grepи sedдля извлечения ключа сортировки и указать только определенные столбцы для сортировки:

grep -H kg *.dat \
  | sed 's/^\([^:]\+\):\([0-9.]\+\)kg \+\([0-9.]\+\)m.*$/\2 \3 \1/' \
  | sort -t' ' -k1,2 -g

Пример вывода:

12 1.6 First2_Last2.dat
18 1.2 First1_Last1.dat

решение2

Если каждый из ваших файлов содержит только одну точку отсчета (линию), то может подойти что-то простое:

for x in *.dat ; do     
    echo $(< "$x") $x    # print contents of file and add the filename 
done  |  sort -nsk2,2    # stable sort by the second column.

Я быстро протестировал сортировку GNU и не заметил проблем с единицами измерения или десятичными знаками, но я не даю никаких гарантий.

решение3

Возможно, использовать (последнюю версию) GNU awk — предполагая, что под «файлом .dat» вы просто подразумеваете текстовый файл, разделенный пробелами:

awk -v sort=2 '
  {
    gsub(/kg|m/,"",$0);
    a[$sort]=$0 FS FILENAME;
  }
  END {
    PROCINFO["sorted_in"]="@ind_num_asc";
    for (i in a) print a[i];
  }' *.dat

где переменная sortзадает столбец для сортировки ( 1или 2); или как однострочный

awk -v sort=1 '{gsub(/kg|m/,"",$0); a[$sort]=$0 FS FILENAME}; END{PROCINFO["sorted_in"]="@ind_num_asc"; for (i in a) print a[i]}' *.dat

Тестирование

$ awk -v sort=1 '{gsub(/kg|m/,"",$0); a[$sort]=$0 FS FILENAME}; END{PROCINFO["sorted_in"]="@ind_num_asc"; for (i in a) print a[i]}' *.dat
12 1.6 First2_Last2.dat
18 1.2 First1_Last1.dat

и

$ awk -v sort=2 '{gsub(/kg|m/,"",$0); a[$sort]=$0 FS FILENAME}; END{PROCINFO["sorted_in"]="@ind_num_asc"; for (i in a) print a[i]}' *.dat
18 1.2 First1_Last1.dat
12 1.6 First2_Last2.dat

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