数字の後に「a」と「aa」をgrepする方法は?

数字の後に「a」と「aa」をgrepする方法は?

私の.txtファイルには次の行が含まれています。

1a
1aa
2a
2aa

「a」側に対して1つの特定のタスクを実行し、「aa」側に対して別の特定のタスクを実行したいと思います。より正確で明確に言えば、当事者「a」に対して私が実行する作業は、当事者「aa」に適用しないでください。になります。

たとえば、

  • 「aa」側ではディレクトリに移動したい
  • 「a」側の場合は、複数のディレクトリに移動したいと思います。

私のスクリプトでこれをどのように実行できますか?

答え1

grep -xE '[0-9]+a'

xGrepsは、10以上の10進数の後に10進数を含む行のみを検索しますa

grep -xE '[0-9]+aa'

aa.

-Eある拡張正規表現必須+。デフォルトの正規表現を有効または無効にすることで、-x次のことができます。

grep '^[0-9]\{1,\}a$'

^$行の先頭と末尾でそれぞれ一致し、\{1,\}BREはEREと同じです+(一部のgrep実装ではこれをサポートし、\+いつでも使用できます[0-9][0-9]*)。

答え2

正規表現aも「aa」と一致するため、スクリプトで「aa」を最初に処理する必要があります。

別のオプションは、Perl準拠正規表現(PCRE)を使用することです。 grepには-P警告とともにこれを有効にするオプションがあります。

これは非常に実験的で、grep -P実装されていない機能について警告することができます。

(少なくとも私が持っているバージョンではオプションを削除したのか、新しいバージョンで警告を変更/削除したのかわかりません)、またはを使用できます。これにより、「a」の場合、perl同様の正規表現が機能します。/a(?!a)/

答え3

#!/bin/sh

while read word; do
    case "$word" in
        *aa)    printf 'Got double "a": %s\n' "$word"   ;;
        *a)     printf 'Got single "a": %s\n' "$word"   ;;
        *)      printf 'Got weirdness:  %s\n' "$word"   ;;
    esac
done <file.in

次のサンプルデータを使用してこのコマンドを実行しますfile.in

Got single "a": 1a
Got double "a": 1aa
Got single "a": 2a
Got double "a": 2aa

既存のループの周りにファイルを繰り返し展開できますwhile

#!/bin/sh

for name in ./*.in; do
    while read word; do
        case "$word" in
            *aa)    printf 'Got double "a": %s\n' "$word"   ;;
            *a)     printf 'Got single "a": %s\n' "$word"   ;;
            *)      printf 'Got weirdness:  %s\n' "$word"   ;;
        esac
    done <"$name"
done

これは、入力したファイルがパターンと一致し、*.in現在のディレクトリにあると仮定します。

答え4

aaとサフィックスを一致させることができますaa$。サフィックスを一致させることは論理的にも終わるため、a少し難しいです。そのため、単一のaと一致する必要があります。これは、aを除くすべての文字を含む反転文字クラスです。aaa[^a]a$[^a]

関連情報