
input.txt
テキストファイル( )から、2つのパターン(string1
とstring2
)が見つかった場合、行を削除したいのですが同じ行、使用sed
。
試しています:
sed -i "/\b\(string1\|string2\)\b/d" input.txt
、しかしこれはstring1
ORを含む行を削除しますstring2
。
答え1
sed -i "/string1.*string2\|string2.*string1/d" input.txt
これにより、string1 が string2 の前にある行、または string2 が string1 の前にある行が削除されます。行を削除するには、両方の文字列がどちらの順序であっても行に存在している必要があります。
答え2
sed -ie '/string1/!b' -e '/string2/d' file.txt
これにより、順序に関係なくstring1
、と の両方を含む行が削除されます( を含む行でを検索する場合のように重複する場合もあります)。string2
foobar
barbaz
foobarbaz
-i
上記は GNU 拡張です。別の GNU 固有のソリューション¹:
awk -i /usr/share/awk/inplace.awk '!(/string1/ && /string2/)' file.txt
移植性を考えると、おそらくperl
ここで以下を使用します:
perl -ni -e 'print unless /string1/ && /string2/'
¹使ってはいけません-i inplace
は、まず現在の作業ディレクトリから拡張機能(または)gawk
をロードしようとしますが、そこに誰かがマルウェアを仕掛けている可能性があります。で提供される拡張機能のパスはシステムによって異なる場合があります。inplace
inplace
inplace.awk
inplace
gawk
gawk 'BEGIN{print ENVIRON["AWKPATH"]}'
答え3
使用楽(旧称 Perl_6)
~$ raku -ne '.put unless .match(/ foobar / & / barbaz / ) ;' file
または
~$ raku -ne '.put unless grep({ / foobar / & / barbaz / }, $_ ) ;' file
上記は、Raku を使用して OP のタスクを実行する一般的な 2 つの方法です。Raku の注意点は、ブロックの後にコンマが必要であることを除いて、Perl の注意grep
点と似ています。代わりにメソッド呼び出しを使用することもできます。その場合、括弧内の記述を気にする必要はありません。grep
.grep
$_
上記のどちらのコード例も、2つの文字列を含む行を削除します。順序に関係なく、また文字列が重複しているかどうかに関係なく。例えば:
サンプル入力:
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
サンプル出力(上記のいずれかのコード例):
1 foo
2 bar
3 baz
4 foobar
5 foobaz
6 barbaz
7 foobar foobaz
8 foobaz barbaz
上記のコードは、重複する string1 と string2 を含む 13 行目を含む、9 行目から 13 行目を削除しますfoobarbaz
。定義された順序で (重複せずに) 出現する文字列を削除する必要がある場合、Raku でそれを実行することもできます。
~$ raku -ne '.put unless m/foobar .* barbaz/;' file
foobar barbaz
上記では、9 行目と 10 行目が削除されますfoobar foobaz barbaz
。
Raku正規表現を使用すると、できる:overlap
(または:ov
) パラメータ/副詞を使用して、重複する 2 つの文字列を検出します。下の最初のリンクを参照してください。
https://docs.raku.org/language/regexes#オーバーラップ
https://docs.raku.org/language/regexes
https://raku.org