решение 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
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
отсортирует даты в правильном порядке месяц / день. Обратите внимание, что это также зависит от вашего языкового стандарта: если ваш файл журнала и ваша среда используют другую локализацию, это не сработает. Без этого они будут правильно сгруппированы по месяцам и отсортированы по дате в течение каждого месяца.
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
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
удаляет первый поле строки - которое существует только потому, что оно изначально скопировало его туда.