Как я могу отсортировать .txt файл по двум столбцам?

решение perl. Даже если некоторые из них не могут быть указаны, это невозможно, Я нашел одну, но в целом простой матч и замена невозможны, и даже хуже из-за отставания NFA результат может быть неожиданным.

В общем, и это надо сказать, проблема дает разные результаты, которые зависят от порядка и длины кортежей замены, т.е.:

A B
AA CC

и вход AAA дает результат в BBB или CCB.

Здесь код:

#!/usr/bin/perl

$v='if (0) {} ';
while (($a,$b)=split /\s+/, <DATA>) {
  $k.=$a.'|';
  $v.='elsif ($& eq \''.$a.'\') {print \''.$b.'\'} ';
}
$k.='.';
$v.='else {print $&;}';

eval "
while (<>) {
  \$_ =~ s/($k)/{$v}/geco;
}";  
print "\n";


__DATA__
A    B
B    A
abba baab
baab abbc
abbc aaba

Checkerbunny:

$ echo 'ABBabbaBBbaabAAabbc'|perl script
$ BAAbaabAAabbcBBaaba
1
31.07.2014, 04:31
2 ответа

sort позволяет сортировать по определенным полям с помощью опции -k :

sort -k11 -k1,2 data

сначала сортирует по полю 11 (имя пользователя), а затем по полям 1 и 2 вместе (дата) . Обратите внимание, что здесь важен порядок : он сначала сортируется по первому параметру -k и использует следующий для разрыва связей (и так далее).

Это очень зависит от точного вывода, который у вас есть - каждая последовательность пробелов является разделителем полей, поэтому «поиск не удалось» - это три разных поля.

При редактировании создается впечатление, что у ваших реальных данных есть поля, разделенные табуляцией, хотя я не могу понять, где находятся табуляции в этом случае. Если это так, вам необходимо указать буквенную табуляцию в качестве аргумента для -t - sort не понимает экранирования, и ваша оболочка, вероятно, не расширяется \ t либо. Либо нажмите Ctrl-V Tab , чтобы ввести туда буквальный символ табуляции, либо замените его: что-то вроде «$ (echo -ne '\ t')» - один из вариантов. В этом случае замените соответствующие номера полей в.

-k5,5n - это числовая сортировка только для поля 5, поскольку никакие из ваших данных не являются числовыми, что выглядит как ошибка.


GNU sort и некоторые другие включают расширение сортировки -M month , которое можно использовать для упорядочивания месяцев. Это может быть доступно вам, а может и не быть; он также есть в FreeBSD и OS X , но не в других BSD и не коммерческих Unices. Если он доступен, -k1,1M -k2,2n отсортирует даты в правильном порядке месяц / день. Обратите внимание, что это также зависит от вашего языкового стандарта: если ваш файл журнала и ваша среда используют другую локализацию, это не сработает. Без этого они будут правильно сгруппированы по месяцам и отсортированы по дате в течение каждого месяца.

2
27.01.2020, 23:38
sed -n 's/\(.*user: \)\([^ ]*\)$/\2 \1\2/p' <<\DATA |\
sort -t' ' -k1,1 -k2,3M |\
sed 's/[^ ]* //'
Feb  7  domainserver dovecot[37495]: auth(default): od(tjones): lookup failed for user: tjones
Feb  8  domainserver dovecot[37495]: auth(default): od(tjones): lookup failed for user: tjones
Feb  5  domainserver dovecot[37495]: auth(default): od(lbones): lookup failed for user: lbones                                                        
Jan  7  domainserver dovecot[37495]: auth(default): od(chaz): lookup failed for user: chaz                                                            
Mar  7  domainserver dovecot[37495]: auth(default): od(lbones): lookup failed for user: lbones                                                        
DATA

OUTPUT

Jan  7  domainserver dovecot[37495]: auth(default): od(chaz): lookup failed for user: chaz
Feb  5  domainserver dovecot[37495]: auth(default): od(lbones): lookup failed for user: lbones
Mar  7  domainserver dovecot[37495]: auth(default): od(lbones): lookup failed for user: lbones
Feb  7  domainserver dovecot[37495]: auth(default): od(tjones): lookup failed for user: tjones
Feb  8  domainserver dovecot[37495]: auth(default): od(tjones): lookup failed for user: tjones

Это сначала обрезает данные, выбирая только строки, содержащие строку user: , и копируя следующее поле в заголовок строки. Итак, учитывая следующие данные:

*CRUFT*user: nospaces$

Где $ представляет конец строки, первое, что делает sed , это:

nospaces *CRUFT*user: nospaces$

... copy nospaces в начало линии. Это обычная практика для такого рода операций, потому что часто даже изменение числа полей на 1 или 2 в любой из строк может существенно повлиять на сортировку . Намного лучше скопировать важные поля в начало строки, чтобы отсортировать только по ним. Во всяком случае, вот что здесь происходит.

Итак, sed передает свои отредактированные данные через канал | в sort , который сортирует сначала по первому полю - имени пользователя - а затем по ] MONTH в -k ey, объединяющем второе и третье поля. В результате все строки сгруппированы по имени пользователя, а каждая группировка отсортирована по дате.

Последний sort передает свои данные обратно в sed поверх другого | pipe , а sed удаляет первый поле строки - которое существует только потому, что оно изначально скопировало его туда.

0
27.01.2020, 23:38

Теги

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