Сортировка отдельных строк в файле
У меня есть файл, который имеет много строк, каждая из которых состоит из списка через запятую. Я хотел бы отсортировать каждую из этих строк.
Если бы у меня была одна строка, это было бы легко:
<file tr ',' '\n' | sort | tr '\n' ','
Но если я сделаю это с моим файлом, он объединит все строки, которые мне не нужны. Как я могу ограничить это?
3 ответа
Это (довольно) легко в Perl:
#!/usr/bin/env perl
use strict;
use warnings;
$, = ",";
while (<>)
{
chomp;
my @fields = split /,/;
my @sorted = sort(@fields);
$sorted[scalar(@sorted)-1] .= "\n";
print @sorted;
}
Хитрость заключается в сохранении отсортированного массива, чтобы можно было добавить новую строку к последнему элементу массива, чтобы строки, заканчивающиеся запятой, не появлялись. Если это не имеет значения, тогда он более компактен - замените последние три строки цикла на:
print sort(@fields), "\n";
вход
x,b,z,a,c,e,f,g,d
3,19,12,17,16,19,18,17,20,16
Выход
a,b,c,d,e,f,g,x,z
12,16,16,17,17,18,19,19,20,3
Компактный код
Поскольку это Perl, есть способы сжать его:
perl -l -p -a -F, -e '$_ = join(",", sort(@F))'
Это:
-l
autochomp и обрабатывать переводы строк.-p
автоматически читать каждую строку ввода, обрабатывать ее сценарием и печатать после каждой строки.-a
разбить входные строки на массивF
на основе разделителя полей.-F,
разделитель полей - это запятая.-e
сопровождается программой.- Программа устанавливает переменную по умолчанию,
$_
, к списку отсортированных запятых значений в массивеF
,
Perl обрабатывает все остальное.
Вы можете избежать чрезмерного количества конвейеров и выполнить всю сортировку в GNU awk:
awk '{split($0, a, ","); n=asort(a);
for (i=1; i<=n; i++) printf "%s%s", a[i], (i<n)?OFS:RS}' OFS=, file
Вы должны были бы сделать это построчно. Используйте цикл:
while read -r line; do
echo "${line}" | tr ',' '\n' | sort | tr '\n' ','
done < file
(Высказывание <file tr ',' '\n'
заменит запятые символами новой строки во всем файле.)