私の.txtファイルには次の行が含まれています。
1a
1aa
2a
2aa
「a」側に対して1つの特定のタスクを実行し、「aa」側に対して別の特定のタスクを実行したいと思います。より正確で明確に言えば、当事者「a」に対して私が実行する作業は、当事者「aa」に適用しないでください。になります。
たとえば、
- 「aa」側ではディレクトリに移動したい
- 「a」側の場合は、複数のディレクトリに移動したいと思います。
私のスクリプトでこれをどのように実行できますか?
答え1
grep -xE '[0-9]+a'
x
Grepsは、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を除くすべての文字を含む反転文字クラスです。aa
a
[^a]a$
[^a]