Ubuntu 20.04でBashを使用しています。
私はファイルを持っています:
Hello hi 123
if a equals b
you
one abc two three four
dany uri four 123
sed
たった4ワードの行を見つける必要があります。これは私が書いたコードですが、うまくいかずにファイルを正確に印刷します。
sed "/[a-Z0-9+]{4}/g" F1
ベストアンサー1
この問題は、次のようにフィールドを簡単に計算できるツールで解決する必要がありますawk
。
$ awk 'NF == 4' file
if a equals b
dany uri four 123
これは、現在のレコードのフィールド数を保持するNF
特殊変数を使用します。awk
デフォルトでは、レコードは1行で、フィールドは、行の先頭または末尾にある空のフィールドを除いて、1つ以上の空白文字(タブまたはスペース)で区切られた部分文字列です。上記のショートプログラムは、awk
正確に4つのフィールドを含むすべての行を出力します。
を使用する場合は、sed
スペースで区切られた部分文字列を一致させる必要があります。
sed
デフォルトの正規表現はデフォルトで使用され、表示される式は拡張正規表現修飾子を使用します{4}
。基本正規表現に対応する内容が作成されます\{4\}
。また、無効な文字範囲を使用しており、a-Z
使用したい文字クラスをで書くことをお勧めします[[:alnum:]]
。つまり、すべての英数字と一致するものです(includeが+
スペルが間違っていると仮定)。 「予約済みスペース」からデータをインポートするための末尾のg
コマンドが間違っているようです。
ここで私の一般的なアイデアは、各単語(空白ではなく1つ以上の文字)を単一の単語にx
圧縮してから、すべての空白文字(タブまたはスペース)を削除することです。結果の文字列がある場合はxxxx
元の行を印刷します(そうでない場合は行を削除し、すぐに次のループを開始します)。
sed -e h \
-e 's/[^[:blank:]]\{1,\}/x/g' \
-e 's/[^x]//g' \
-e '/^xxxx$/!d' \
-e g file
ここで、元の行は最初を使用して「予約済みスペース」に保存し、印刷する必要があるh
場合は再度取り出し、g
最後に使用します。 2番目から最後の行までd
のコマンドが実行されると、g
最後の行は考慮されません。
または拡張正規表現を使用してください。
sed -E -e h \
-e 's/[^[:blank:]]+/x/g' \
-e 's/[^x]//g' \
-e '/^xxxx$/!d' \
-e g file
テスト:
$ sed -e h \
> -e 's/[^[:blank:]]\{1,\}/x/g' \
> -e 's/[^x]//g' \
> -e '/^xxxx$/!d' \
> -e g file
if a equals b
dany uri four 123
[[:alnum:]]
(空白ではなく)代わりにクラスで単語文字を定義するには、[^[:blank:]]
上記の式を[^[:blank:]]
に変更します。[[:alnum:]]
違いは、GNU/Linux
orなどの文字列がUnix-system
各単語ではなく2つの単語として扱われることです。