grep, Pipe, Cat を使用した混合英数字入力出力

grep, Pipe, Cat を使用した混合英数字入力出力

入力として混合単語のリストがあります。

azert12345
a1z2e3r4t5
a1z2e3r455

実行するコマンドラインは次のとおりです。

cat file.txt | grep -E "[[:digit:]]{5}" --color

私が達成したいこと:

grep前述のパターンを使用して、「azert12345」と「a1z2e3r4t5」という単語のみを印刷します。それはまるでgrep -E "[[:digit:]]{5}"

grep -E "[[:alpha:]]{5}[[:digit:]]{5}"最大桁数5、最大アルファベット文字数5を使用して「azert12345」などの単語を印刷するのは簡単ですが、問題は次のとおりです。 a1z2e3r4t5のような混合単語をどのように印刷しますか?

「a1z2e3r4t5」は例示に過ぎず、処理すべきデータ量ははるかに多い。

この問題は私を3日間狂ったようにし、それは宿題ではありませんでした。 Linuxコマンドについてもう一度学びましょう。私は助けが必要です。

答え1

IMHO これは、次の理由でawkまたはperlでより簡単です。grepと論理演算子(特にgrepには自然演算子はありませんAND)。例えば

awk 'gsub(/[a-z]/,"&") == 5 && gsub(/[0-9]/,"&") == 5' file

または

perl -ne 'print if tr/[a-z]// == 5 && tr/[0-9]// == 5' file

各文字セットの正確に5文字を含む行が印刷されます。


grepの使用にこだわったら、次のように動作します。

grep -xE '([^a-z]*[a-z][^a-z]*){5}' file | grep -xE '([^0-9]*[0-9][^0-9]*){5}'

答え2

使用しないでください正しいツールバラより、しかし少なくとも代わりとして:

while read i; do 
  foo=$(echo -n $i | sed 's/[a-z]//g' | wc -c) && bar=$(echo -n $i | sed 's/[0-9]//g' | wc -c)
  [[ $foo -eq 5 && $bar -eq 5 ]] && echo "$i  has five digits and five alphas" 
done < file

文字を削除して残すのは数字です。徹底的にするには、数字を削除して残ったのは文字だけです。各結果を変数に保存します。

foo=$(echo -n $i | sed 's/[a-z]//g' | wc -c) && bar=$(echo -n $i | sed 's/[0-9]//g' | wc -c)

変数の長さが5文字の場合、文字列は5つの数字と5つの文字です。

[[ $foo -eq 5 && $bar -eq 5 ]] && echo "$i  has five digits and five alphas" 

出力:

azert12345  has five digits and five alphas
a1z2e3r4t5  has five digits and five alphas

このロジックに問題がありますか?

関連情報