
元の文字列は次のようになります。
str-str001-002_01
str-str005-006_05
数字の前、アンダースコアの後の文字列を抽出したいので、次のようになります。
str-str_01
str-str_05
sed は次のようにパターンをグループに分割できたことを覚えています。
sed -n 's/\(^.*\)\([0-9]-[0-9]\)\(.*$\)/\1\3/p'
しかし、次のように印刷されます:
str-str0002_01
それから、[0-9] は 1 つの数字だけであることを思い出し、+ 記号または * 記号で試してみました。すると空の結果が返されます。
追伸:使用することで
echo 'str-str001-002_01' | sed -n 's/\(^.*\)\([0-9]-[0-9]\)\(.*$\)/\2/p'
一致していることがわかります1-0
。
次に、次のように試しました:
echo 'str-str001-002_01' | sed -n 's/\(^.*\)\([0-9]\+-[0-9]\+\)\(.*$\)/\2/p'
最初の2つの数字を残し、一致するのは
1-002
ではどうやって一致させるか001-002
答え1
これにより、必要な出力が提供されます。
sed -nE 's/^([^0-9]*).*_([^_]+)$/\1_\2/p'
例からの出力
str-str_01
str-str_05
説明
sed -nE 's/…/…/p'
- EREを使用し、一致しない限り行を印刷しない^
- 行の先頭にアンカー([^0-9]*)
- 可能な限り長いパターンに一致します。少なくとも 1 つの数字以外の文字が含まれます。.*_
- 可能な限り一致(何も含まない)し、その後に「_
」が続く([^_]+)
- アンダースコア以外のできるだけ長いパターン(少なくとも 1 文字)に一致します$
- 行末にアンカー\1_\2
- 行全体を最初の(…)
一致「_
」と2番目の(…)
一致で置き換えます
試行が期待どおりに機能しなかった理由は、*
(および+
) が貪欲であるためです。つまり、先行するアトムに一致する文字をできるだけ多く消費します。したがって、 の ERE を の(.*)([0-9]+)
ようなものに適用するとabc123
、.*
は を消費しabc12
、[0-9]+
だけが一致するようになり3
ます。"数字ではない" は最初の一致を制限します:および([^0-9]*)([0-9]+)
を取得します。abc
123
答え2
$ cat file
str-str001-002_01
str-str005-006_05
$ sed 's/[0-9]\{3\}-[0-9]\{3\}//' file
str-str_01
str-str_05
ここでの置換コマンドは、3 桁の数字が連続しているNNN-NNN
部分を一致させて削除します。NNN
合わせる少なくとも一つの数字、1,
の代わりに使用3
:
$ sed 's/[0-9]\{1,\}-[0-9]\{1,\}//' file
str-str_01
str-str_05
これは、+
拡張正規表現で を使用することに相当します。 がデフォルトで使用する正規表現はsed
「基本」正規表現であり、+
リテラルプラス文字と一致します。 ほとんどのsed
実装では、 を使用した拡張表現もサポートされています-E
。
$ sed -E 's/[0-9]+-[0-9]+//' file
str-str_01
str-str_05
*
のようにを使用すると[0-9]*-[0-9]*
、 のダッシュstr-str
(周囲に 0 桁の数字がある) と一致するため機能しません。
行全体を一致させて、保持したいビットをキャプチャする必要がある場合は、これも実行できます。次のコマンドは、アンダースコアを含む最初の非数字と最後のビットをキャプチャします。
$ sed 's/\([^0-9]*\).*\(_.*\)/\1\2/' file
str-str_01
str-str_05
しかし、これは解読するのが少し難しく、質問で言及されていない文字列の始まりと終わりについての仮定をしています。たとえば、始まりには削除したい数字の前の数字を含めることはできません。また、文字列の終わりは最後文字列のその部分に複数のアンダースコアがある場合、削除する数字の後ろにアンダースコアを付ける必要はありません。
この式にさらに追加して、ビットのみがキャプチャされないようにすることもできますNNN-NNN
が、そうすると式の理解がさらに難しくなります。