sed を使用して各行の先頭からさまざまな長さの数値をキャプチャ

sed を使用して各行の先頭からさまざまな長さの数値をキャプチャ

次の形式のファイルに取り組んでいます。

12345:ABCDEFG

789:HIJK

4963158:LMNOPQRSTUV

各行はさまざまな長さで始まり、その後にコロン、さまざまな長さの文字列が続きます。以下のように、各行の先頭にある数字だけをキャプチャして新しいファイルに入れたいと思います。

12345

789

4963158

これは私が得たものに最も近いですが、数字だけでなく行全体を印刷します。

sed -r 's/([^0-9]+d)(:)([A-Z]+)$/\1/' example.txt >> justnumbers.txt

私が文法的に何を間違っているのだろうか?

答え1

時には問題を別の方法で見ると、より簡単な答えが得られます。

「以前のすべての数字を維持したい」と考えるのは非常に合理的です。もう一つの観点では、「最初から最後まですべてを捨てたい」と見ることもできる。

これにより

s/:.*//

sedコマンドで。

例えば

$ cat x
12345:ABCDEFG
789:HIJK
4963158:LMNOPQRSTUV

$ sed 's/:.*//' x
12345
789
4963158

答え2

ポイントが:各行の最初の行の残りの部分を返すことである場合は、次のようにします。

<your-file cut -d: -f1

この-sオプションを追加すると、すべて:

:1つ以上のASCII番号と1つ以上のASCII大文字からなる行の残りの部分を返し、パターンと:一致しない行を削除するにはsed//を使用できますawkperl

<your-file sed -n '^\([0123456789]\{1,\}\):[ABCDEFGHIJKLMNOPQRSTUVWXYZ]\{1,\}$/\1/p'

または:

<your-file LC_ALL=C sed -n 's/^\([0-9]\{1,\}\):[A-Z]\{1,\}$/\1/p'

(ロケールは、これらの範囲が最初のコマンドで明示的に設定されたものと同じであることをC保証する唯一のものです。)[0-9][A-Z]

または、sed正規表現拡張-Eオプションをサポートしている場合E(60年代ではなく70年代から拡張されましたが、実装はsed90年代後半までサポートを追加し始めませんでした):

<your-file LC_ALL=C sed -nE 's/^([0-9]+):[A-Z]+$/\1/p'

または、以下を使用してくださいperl(80年代の正規表現を使用)。

<your-file perl -lne 'print $1 if /^(\d+):[A-Z]+$/'

pcregrep同様の正規表現をgrep使用し、最初のキャプチャグループの出力をサポートする実装です。perl-o<n>n

<your-file pcregrep -xo1 '(\d+):[A-Z]+'

一部grepの実装には-oオプションがありますが、完全一致のみを出力しますが、一部の実装では、類似-P演算子を使用して一致を含めずに内容を調べることができるPerlなどの正規表現の使用をサポートしています。

<your-file grep -Po '^(\d+)(?=:[A-Z]+$)'

(?=...):1つ以上の[A-Z]s(perl正規表現ではロケールを区別しないためLC_ALL=C必要ありません)、行の末尾が続く場合は、行の先頭にある1つ以上の数値シーケンスと一致します。


公平に言えば、それ以来彼らはすべて進化してきました、特にPerlはそうしました。 1970年代後半のEREは+?および|(もっと重要なのは一致のための新しいアルゴリズム)を追加しましたが、逆\x参照が失われました。\{min,max\}は80年代後半にBREに追加され(+そして同じことができます?{min,max}、後でEREに再追加されましたが、以前のバージョンとの互換性が損なわれたため、必ずしもそうではありません。 POSIXはいくつか、、[[:class:]](より良いかより価値があるため)を導入します。 BRE/ERE の一部の実装では、または 。[[=x=]][[.x.]]perl\d*?

答え3

この試み:

sed -E 's/([0-9]+):[A-Z]+/\1/' example.txt

-E同じ-rですが、もう少し標準になりました。

正規表現の問題は、[^0-9]式の先頭()に負の角括弧を使用してからリテラルd文字を一致させることです。

また、不要な追加のキャプチャグループも削除しました。

全体的に大変な努力をしました!あなたは本当に近いです。正規表現を使い始めるときに直面する質問は次のとおりです。

答え4

使用幸せ(以前のPerl_6)

~$ raku -pe 's/^ (\d+) \: .* $/$0/;'  file

#OR

~$ raku -pe 's/^ \d+ <( \: .* $//;'  file

さまざまな正規表現の実装を見ると、共通のトピックを見つけるのに役立ちます。 PerlとRakuの場合、-peコマンドラインフラグはsed同様の動作を提供し、各行でコードを実行して自動的に印刷します。

上記の最初のRakuの例では、^文字列の先頭\d+(1つ以上の数字)、:コロン(バックスラッシュエスケープ)、および文字列の終わりまで(つまり行).*0文字以上のキャプチャを行います。$Rakuキャプチャは、一致するオブジェクトの半分(つまり、行全体)を置き換えるために使用されるキャプチャされた$0数字で始まります。$0s///

上記の2番目のRakuの例は、反対のアプローチをとります。^文字列の先頭\d+(1つ以上)と一致し、その後に:コロン(バックスラッシュでエスケープされている)と.*文字列$の終わりまで(たとえば行)。ただし、<(「キャプチャタグ」は、Rakuの正規表現エンジンに\d+一致するオブジェクトから前の数字を削除し、後の数字だけを残すように指示します。置換では、一致するオブジェクトに残っているすべての項目が削除されるため(別の項目に置き換える)、文字列の先頭に数字だけが残り\d+ます。

https://docs.raku.org/言語/regexes#Capture_markers:_%3C(_)%3E
https://docs.raku.org/言語/regexes
https://raku.org

関連情報