Grep は複数の一致で失敗します。

Grep は複数の一致で失敗します。

検索パターンを探したいが、一意の一致が 1 つしかない場合にのみ成功し、一致する行を出力します。 2行が一致すると、grepは失敗したり何も印刷しません。

答え1

ではこれを行うことはできませんが、grep単に一致するアイテムの数を数えることができます。どのシェルを使用しているのか、どのOSを使用しているのかはわかりませんが、grep以下はこれを実行できるbash関数の例です。

maxOne() (
    pattern="$1"
    file="$2"
    IFS=$'\n'
    set -f

    results=( $(grep -m2 -- "$pattern" "$file") )
    if [ "${#results[@]}" -eq 1 ]; then
        printf -- '%s\n' "${results[@]}"
        return 0
    else
        return 1
    fi
)

次の行をファイルに追加するか、~/.bashrc実行中のbashセッションの端末に貼り付けると、次のことができます。

maxOne foo file

fooで検索するにはfile-mここで使用されているオプション(最大結果)は、2つのgrepゲームの後に終了する効率のためのものであり、すべてのバージョンでサポートされていないため、grepエラーが発生した場合は単に削除してください。これは必須ではなく、作業を高速化するだけです。

重要: 複数行検索文字列では機能しません。サポートしgrep -zている場合は、複数行の検索文字列を使用できますgrep。複数行の検索パターンを処理できる必要がある場合は、他のアプローチが必要です。また、これは空行に一致するパターン(たとえばgrep '^$' file)では機能しません。ステファンのソリューション空行は処理されるので、これが問題であれば、これはより良い選択になります。私とは異なり、彼は複数のファイルを処理することができますが、これは良いボーナスです。

答え2

次のことができます。

unique_egrep() (
  export ERE="$1"; shift
  exec gawk -e '
    BEGIN               {ret = 1}
    BEGINFILE           {n = 0}
    $0 ~ ENVIRON["ERE"] {if (n++) nextfile; found = $0}
    ENDFILE             {if (n == 1) {print FILENAME":"found; ret = 0}}
    END                 {exit ret}' -E /dev/null "$@"
)

他のunique_egrep pattern *.txt例。

ここで使用-e 'code' -E /dev/null(代替'code')スキル任意のファイルパスを処理する機能。

-e-EおよびすべてGNU拡張ですBEGINFILE(現在は他の多くの実装でも見ることができます)。ENDFILEnextfilenextfile

関連情報