
Gostaria de excluir uma linha de um arquivo de texto ( input.txt
) se dois padrões ( string1
e string2
) forem encontrados nomesmolinha, usando sed
.
Estou tentando:
sed -i "/\b\(string1\|string2\)\b/d" input.txt
, mas isso está excluindo linhas contendo string1
OR string2
.
Responder1
sed -i "/string1.*string2\|string2.*string1/d" input.txt
Isso excluirá qualquer linha onde string1 apareça antes de string2, OU string2 apareça antes de string1. Ambas as strings devem estar na linha, em qualquer ordem, para que a linha seja excluída.
Responder2
sed -ie '/string1/!b' -e '/string2/d' file.txt
Isso exclui linhas que contêm ambos string1
e string2
independentemente da ordem (pode até se sobrepor como ao procurar foobar
em barbaz
uma linha que contém foobarbaz
).
-i
acima é uma extensão GNU. Outra solução específica do GNU¹:
awk -i /usr/share/awk/inplace.awk '!(/string1/ && /string2/)' file.txt
Portavelmente, você provavelmente usaria perl
aqui:
perl -ni -e 'print unless /string1/ && /string2/'
¹não use-i inplace
as gawk
tenta carregar primeiro a inplace
extensão (como inplace
ou inplace.awk
) do diretório de trabalho atual, onde alguém poderia ter plantado malware. O caminho da inplace
extensão fornecida gawk
pode variar de acordo com o sistema, consulte a saída degawk 'BEGIN{print ENVIRON["AWKPATH"]}'
Responder3
UsandoRaku(anteriormente conhecido como Perl_6)
~$ raku -ne '.put unless .match(/ foobar / & / barbaz / ) ;' file
OU
~$ raku -ne '.put unless grep({ / foobar / & / barbaz / }, $_ ) ;' file
Acima estão duas maneiras gerais de realizar a tarefa do OP usando Raku. A nota grep
em Raku é semelhante à grep
em Perl, exceto que é necessária uma vírgula após o bloco. Você também pode usar a .grep
chamada de método e não precisa se preocupar em escrever $_
entre parênteses.
Qualquer um dos exemplos de código acima excluirá linhas que contêm duas strings,independentemente da ordem E independentemente de as strings se sobreporem.Por exemplo:
Entrada de amostra:
1 foo
2 bar
3 baz
4 foobar
5 foobaz
6 barbaz
7 foobar foobaz
8 foobaz barbaz
9 foobar barbaz
10 foobar foobaz barbaz
11 foobaz barbaz foobar
12 barbaz foobar foobaz
13 foobarbaz
Exemplo de saída (qualquer exemplo de código acima):
1 foo
2 bar
3 baz
4 foobar
5 foobaz
6 barbaz
7 foobar foobaz
8 foobaz barbaz
O código acima exclui as linhas 9 a 13, incluindo a linha 13 foobarbaz
que contém string1 e string2 sobrepostas. Se você precisar excluir strings que aparecem em uma ordem definida (e sem sobreposição), Raku também pode fazer isso:
~$ raku -ne '.put unless m/foobar .* barbaz/;' file
Acima remove as linhas 9 e 10: foobar barbaz
e foobar foobaz barbaz
.
Observe que usando Raku regexes vocêpodedetectar duas strings que se sobrepõem, com o parâmetro/advérbio :overlap
(ou ). :ov
Veja o primeiro link abaixo.
https://docs.raku.org/linguagem/regexes#Overlap
https://docs.raku.org/linguagem/regexes
https://raku.org