Grep は、感嘆符が一度表示されるテキスト行を探します。

Grep は、感嘆符が一度表示されるテキスト行を探します。

次の内容を含むファイルがあるとします。

some:text:!someothertext
another:text:!!anothertext

「!」が一度だけ現れるテキスト行だけを探したい。

これが私が持っているもので動作するようですが、より良い方法があるかどうか疑問に思います。

grep -E ':![^!]' my_tex.txt

答え1

awk以下のおよびitを使用して、各行の感嘆符gsub()の数を計算します。このコマンドは、感嘆符が1つだけ含まれている行のみを出力します。&一致する感嘆符を自分のものに置き換えます。

awk 'gsub("!","&") == 1' file

trPerlとその演算子を使用して同様の操作を実行できます。

perl -ne 'print if tr /!/!/ == 1' file

grep次のようにすれば、賢く努力する必要はありません。

grep -F '!' file | grep -v '!.*!'

つまり、単一の感嘆符を含む行を抽出した後、複数の感嘆符を含む行を削除します。これには2つのコマンドをパイピングすることが含まれますが、パイピングの目的は明らかであるため、多くの状況で役に立ちます。特定の部分文字列を避けたいのですが、それでもこのようなことを許可するには、grep2番目のコマンドを単純化できますgrepgrep -v -F '!!'!!!hello!

答え2

私は以下を使用しますsed

sed 's/!/!/2;t1;/!/p;:1 d' file

または複数行に移植可能な方法で:

sed '
    s/!/!/2;t1
    /!/p;:1
    d
' file

あるいは、行印刷を無効にする方が短い場合があります。

sed -n 's/!/!/2;t;/!/p' file

GNU sedとコマンドを使用して、T交換が失敗したことを確認します。

sed '/!/!d;s/!/!/2;T;d' file

!これらはすべて同じように機能します。行の2番目の項目を置き換えます。置換が成功すると(テストを介して)、行に少なくとも2つあるのでtスキップします。!

答え3

awk -F '!' 'NF==2' filename

出力

some:text:!someothertext

答え4

おそらくあなたが望むもの全行一致0個以上のnon!に囲まれた!で構成されます。キャラクター - 何でも

grep -x '[^!]*![^!]*' my_tex.txt

または

grep '^[^!]*![^!]*$' my_tex.txt

関連情報