9838
、など、4文字以外の数字をすべて削除する必要があります6738
。1337
1889
私はこのコマンドがうまくいくと思います:
sed 's/....[^0-9]//g'
.
正規表現のすべての文字を表し、[^0-9]
数値を削除しません。
入力例は次のとおりです。
9228 Hello 8473 World War 1 1914-1918 Hello 8391 World War 2 1939-1945
する:
9228 8473 1914 1918 8391 1939 1945
答え1
次のコマンドで答えることができますgrep
。
入力ファイル:
9228 Hello 8473 World War 1 1914-1918 Hello 8391 World War 2 1939-1945
注文する:
grep -Eo '\<[0-9]{4}\>' file |tr '\n' ' '
長さ4のランダムな数値を返します。
-E
-o
一致する部分だけを印刷するには、拡張正規表現に切り替えます。
出力:
9228 8473 1914 1918 8391 1939 1945
更新された回答:
入力ファイル:
9228 Hello 8473 World War 1 1914-1918 Hello 8391 World War 2 1939-1945
foo1234bar
a1111
12345
0x2222ff
1.3333
2.54321
注文する
grep -oP '(?<![0-9])[0-9]{4}(?![0-9])' file | tr '\n' ' '
否定的な Lookbehind/lookforward を使用した grep:
(?<![0-9])[0-9]{4}
(逆方向否定検索):数字を長さ= 4に一致させ、先行番号がありません[0-9]
。
[0-9]{4}(?![0-9])
(否定的な予測):数字を長さ= 4に一致させ、後に数字がありません。
出力:
9228 8473 1914 1918 8391 1939 1945 1234 1111 2222 3333
答え2
あなたはそれを使用することができますperl
。
perl -nle'print join " ", /(?<![0-9])[0-9]{4}(?![0-9])/g'
これは複数行入力でも機能するため、次のような場合があります。
9228 Hello 8473 World War 1 1914-1918
Hello 8391 World War 2 1939-1945
次の返品情報が届きます。
9228 8473 1914 1918
8391 1939 1945
(-0777
数字を同じ行に表示するには追加してください。)
答え3
POSIX的に:
< file tr -cs 0-9 '[\n*]' | grep -xE '.{4}' | paste -sd ' ' -
答え4
単一のバックスラッシュを使用してs///
POSIXでこれを実行できますが、sed
バックスラッシュがたくさんあります。
sed 's/[^0-9]*\([0-9]\{5,\}\)*[^0-9]*\([0-9]\{4\}\)*.\{0,1\}/ \2/g
' <<\IN
92828 Hello 8473 World War 1 1914-1918 Hello 8391 World War 2 1939-1945
IN
出力
8473 1914 1918 8391 1939 1945
g
5つ以上の数字を含むすべてのシーケンスを最初に拾い、次に数字以外の^
シーケンスをすべて食べます。それからあなたの一致項目だけでなく、他の文字の最後の0または1も含まれます。文全体に一致する式が1つだけ格納されるため、中間スペースを除いてこれが残ります。
しかし、ちょっとした翻訳をすれば状況がより簡単になります。
sed 'y/ /./;s/[0-9]\{4,\}/ & /g;s/\( [^ ]\{4\} \)*[^ ]*/\1/g
' <<\IN
92828 Hello 8473 World War 1 1914-1918 Hello 8391 World War 2 1939-1945
IN
出力
8473 1914 1918 8391 1939 1945
sed
まず、すべてのスペースをドットで音訳してください。次に、4つ以上の数値シーケンスをスペースで囲みます。最後に、空白以外のすべての文字を削除し、空白で囲まれた4つの文字シーケンスを保存します。