У меня есть стандартный вывод или файл не имеет значения:
mela
pera
banana
caffè
mela
pera
banana
caffè
mela
pera
banana
caffè
Я хочу удалить только последнее вхождение « mela
», используя perl
:
mela
pera
banana
caffè
mela
pera
banana
caffè
pera
banana
caffè
как сделать Я делаю это?
perl -lwne '
if ($_ eq "mela") {
if ($i) {
print for splice @buffer, 0, $i;
}
$i = 1+$#buffer;
}
push @buffer, $_;
END {
splice @buffer, $i, 1;
print for @buffer;
}'
-n
считывает ввод (файл или стандартный ввод) построчно.Вместо того, чтобы печатать каждую строку, вы помещаете строки в буфер. Когда вы встречаете mela
, вы заставляете $i
указывать на его позицию в буфере. Когда вы снова встречаете mela
, вы печатаете первую часть буфера до предыдущей mela
. В конце ввода вы печатаете буфер except для последней mela
, на которую указывает $i
.
Не проверено на крайние случаи (несколько mela
следующих друг за другом, mela
в первой/последней строке и т. д.)
В отдельной программе Perl:
#!/usr/bin/perl
# Desc: Repeat everything back, except last occurrence of given string
# Synt: $0 string <infile
## for each input record in reverse order,
## if string not found before, and found now, set flag, else stack record
## print stack
$s = shift."\n"; # get string, append LF
for ( reverse <STDIN> ) {
if ( !$f && $s eq $_ ) { $f=1 }
else { unshift @o,$_ }
}
print @o;
ИЛИ как однострочник для опытных пользователей, в действии:
$ echo -e "11\nmela\n22\nmela\n33" | perl -e '$s=shift."\n";
!$f && $s eq $_ ? $f=1 : unshift @o,$_ for reverse <STDIN>;
print @o;' mela
11
mela
22
33