sed
fornece uma maneira mais simples:
... | sed '/some stuff/ {N; s/^.*\n//; :p; N; $q; bp}' | ...
Desta forma, você exclui a primeira ocorrência.
Se você quiser mais:
sed '1 {h; s/.*/iiii/; x}; /some stuff/ {x; s/^i//; x; td; b; :d; d}'
, em que contagem de i
é a contagem de ocorrências (uma ou mais, não zero).
Explicação de várias linhas
sed '1 {
# Save first line in hold buffer, put 'i's to main buffer, swap buffers
h
s/^.*$/iiii/
x
}
# For regexp what we finding
/some stuff/ {
# Remove one 'i' from hold buffer
x
s/i//
x
# If successful, there was 'i'. Jump to ':d', delete line
td
# If not, process next line (print others).
b
:d
d
}'
Além disso
Provavelmente, essa variante funcionará mais rápido, porque ela lê todas as linhas de descanso e as imprime em uma única vez
sed '1 {h; s/.*/ii/; x}; /a/ {x; s/i//; x; td; :print_all; N; $q; bprint_all; :d; d}'
Como resultado
Você pode colocar este código no seu .bashrc
(ou na configuração do seu shell, se for outro):
dtrash() {
if [ $# -eq 0 ]
then
cat
elif [ $# -eq 1 ]
then
sed "/$1/ {N; s/^.*\n//; :p; N; \$q; bp}"
else
count=""
for i in $(seq $1)
do
count="${count}i"
done
sed "1 {h; s/.*/$count/; x}; /$2/ {x; s/i//; x; td; :print_all; N; \$q; bprint_all; :d; d}"
fi
}
E use desta forma:
# Remove first occurrence
cat file | dtrash 'stuff'
# Remove four occurrences
cat file | dtrash 4 'stuff'
# Don't modify
cat file | dtrash