GNU использует расширенный режим регулярных выражений -E
, чтобы упростить написание регулярных выражений. Используемый подход заключается в немедленном отбрасывании любых неинтересных линий, то есть тех, которые не содержат золота. После этого мы удаляем все не золотые медали, удаляя только цифры перед золотой медалью:
$ sed -Ee '
s/\s*[(][)]\s*/\n/
\|\n.*[0-9]/gold/|!d
:a
/\n$/!{
\|\n([0-9]+)/gold/\S+\s*|{
s//;\1\n/;ba
}
s|\n\S+\s*|\n|;ba
}
s/(^\s*|\s*$)//g
' file.log
Perl делает задачу тривиальной:
$ perl -F'[(][)]' -lane '
(my $p = $F[0]) =~ s/(^\s*|\s*$)//g;
my @A = $F[1] =~ m[\D(\d+)/gold/]g;
print join ";", $p, @A if @A;
' file.log
Результаты:
Player: 9.8.7.6.5.4.3.2.1;10;15
Player: 7.6.5.4.3.2.1.9.8;36
Player: 6.5.4.3.2.1.9.8.7;40
Player: 5.4.3.2.1.9.8.7.6;50;55
Player: 4.3.2.1.9.8.7.6.5;10
Правильный синтаксис для последней команды sed
:
sed -n '/[hlrw]/!p'
или
sed '/[hlrw]/d'
, которые примерно эквивалентны. Соответствующая программа awk
будет
awk '!/[hlrw]/'
Неправильная команда в исходном примере означает «содержит любой символ, не входящий в набор hlrw
», (что верно, если только строка полностью не состоит из символов h
, l
, r
, w
или пусто ), а второе — «найти строки, содержащие любой символ в наборе hlrw
», а затем не печатать их; или «найти строки, включающие набор hlrw
», и удалить их из ввода.
Здесь вам не нужно sed
. Вы могли бы просто сделать:
grep -v '[hlrw]'
Первый (нестандартный -)sed -e 's/\s/\n/g'
также можно заменить на:
tr -s '[:space:]' '[\n*]'
, который транслитерирует и сжимает все последовательности пробелов в символ новой строки.
Это на самом деле оправдало бы использование cat
(, который не нужен для sed
, так как sed
может принимать имена файлов в качестве аргументов и считывать их напрямую ).
Таким образом, альтернативный синтаксис будет
cat roa7.lst gr7.usl | tr -s '[:space:]' '[\n*]' | grep -v '[hlrw]' | sort -u | less -N
, что полностью исключает использование sed
.