次のファイルがあります。
1 foo
1 bar
1 someOtherString
2 contains bar and more
2 test
3 contains a random string
4 some other string
2 don't remove this line bar
2 but remove this line
14 keep this line
21 and also this line
7 bar
このファイルから次のファイルをインポートしたいと思います。
1 foo
1 bar
2 contains bar and more
3 contains a random string
4 some other string
2 don't remove this line bar
14 keep this line
21 and also this line
7 bar
オリジナル:
- 「1」または「2」で始まらない行をすべて保持します。
- 「foo」または「bar」を含むすべての行を保持します。
- 他のすべての行を削除
- 注文をそのままにしてください
答え1
というファイルのデータを考慮してくださいfile
。例の結果を得るための要件は、公開した説明とは少し異なります。
file
次のいずれかの条件に一致するすべての行を保持します。- nor(数字の後にスペースがある)で
1
始めないでください。2
- 含める
foo
かbar
- nor(数字の後にスペースがある)で
- 他のすべての行を削除
- 注文をそのままにしてください
perl
これは、2つの式を一致させ、一致するときにその行を(順番に)印刷することによって表現できます。
perl -ne '( !/^(1 |2 )/ or /foo|bar/ ) and print' file
振り返ってみると、要件全体がわずかに異なるように表現されている可能性があります。
- 各行ごとに順番に
1
行がまたはで始まらない場合は、その行を印刷します。2
foo
またはbar
これはawk
非常に便利にマッピングされます。
awk '!/^(1 |2 )/ || /foo/ || /bar/' file
どちらの場合でも、REは共通の要因を導き、次のようperl
に書き直すことで単純化できます。awk
^(1 |2 )
^[12]
perl -ne '( !/^[12] / or /foo|bar/ ) and print' file
awk '!/^[12] / || /foo/ || /bar/' file
答え2
使用sed
:
$ sed '/^[12]\>/ { /foo/ !{ /bar/ !d; }; }' file
1 foo
1 bar
2 contains bar and more
3 contains a random string
4 some other string
2 don't remove this line bar
14 keep this line
21 and also this line
7 bar
上記のコードは、各行がsed
単語ではなく文字(必要に応じて単一のスペースで置き換えることができます)で始まるかどうかを1
テストします。そうでない場合は、行を印刷します。その場合は、その行の部分文字列をテストしてください。部分文字列が存在する場合は、その行を印刷します。存在しない場合はペアに対して同様のテストを実行し、一致する場合は行を印刷し、一致しない場合は行を削除します。2
\>
foo
bar
ロジックを逆さまに読んでくださいd
。一致せずbar
、一致しないが、foo
または1
で始まる行は削除されます2
。
答え3
Raku(以前のPerl_6)の使用
raku -ne '.put if .grep( !/^ [ 1 | 2 ] \s / | / foo | bar / );'
または
raku -ne '.put if .grep( { !/^ [ 1 | 2 ] \s /} | / foo | bar / );'
または
raku -ne '.put if .grep( (none /^ [ 1 | 2 ] \s /) | / foo | bar / );'
入力例:
1 foo
1 bar
1 someOtherString
2 contains bar and more
2 test
3 contains a random string
4 some other string
2 don't remove this line bar
2 but remove this line
14 keep this line
21 and also this line
7 bar
出力例:
1 foo
1 bar
2 contains bar and more
3 contains a random string
4 some other string
2 don't remove this line bar
14 keep this line
21 and also this line
7 bar
上記は@roaimaのPerl5コードを大まかに翻訳したものです。しかし、これは実際にRakuでの作業ですgrep
。 Rakuでは、!
否定演算子(周辺コードブロックの有無にかかわらず上記のように{...}
)を使用するか、接続(Rakuに関連するnone
)を使用してパターンが存在するかどうかをテストできます。Sets
\s
正規表現に文字が含まれていることがわかります。これは宣言されていない(\s
)空白および/または「...正規表現で引用されていないスペースは通常無視されます...」Rakuでは、基本的にコードを読みやすくします。下記のリンクをご覧ください。
答え4
次のようなマルチベース検索を実行するためにツアーを利用することができます。
$ grep -vP '^(?=[12]\h)(?!.*(?:foo|bar))' file
Pythonはreモジュールと連携して、検索結果の状態に応じて一致およびフィルタリングできます。
python3 -c 'import re, sys
with open(sys.argv[1]) as f:
print(*filter(lambda x: re.match(r"(?![12]\s)",x) or re.search(r"foo|bar",x),f),sep="",end="")
' file