LoginSignup
49

More than 5 years have passed since last update.

[Linux][sed] 文字列から部分抽出する/置換後に特定文字列を使いまわす方法

Last updated at Posted at 2017-03-13

毎回調べるので自分のユースケースでまとめ

sed -e よりも拡張正規表現を使用する sed -r をおすすめします。(本記事は sed -r を前提とします)

使用例

基本

s/^.*(one).*$/\1 のように抽出したい条件をカッコで括り、マッチした順番で連番が振られるので \1 等で取得します。

1つの場合
$ echo "one two three" | sed -r 's/^\s*(one).*$/1: \1/'
1: one
2つの場合
$ echo "one two three" | sed -r 's/^\s*(one)\s+(two).*$/1: \1\n2: \2/'
1: one
2: two

抽出条件の一部が欠けるケースに対応する

よくあるパターンとして、部分抽出に指定している文字が欠けるケースが有ります。

そのままだと失敗する
$ echo " two three" | sed -r 's/^\s*(one)\s+(two).*$/1: \1\n2: \2/'
 two three

その場合は抽出条件に ? をつけることで、存在しないケースに対応できます。(連番はそのまま)

2つの場合
$ echo "one two three" | sed -r 's/^\s*(one)?\s+(two).*$/1: \1\n2: \2/'
1: one
2: two
$ echo " two three" | sed -r 's/^\s*(one)?\s+(two).*$/1: \1\n2: \2/'
1: 
2: two

抽出条件がさらに複数どこか欠けるケースは、抽出条件をさらにグループ化して同じように ? で無い場合に対応できます。(空白の考慮が甘いですが、あくまでも例なので厳密さは気にしないでください・・・)

連番はグループ化のはじめのカッコがある順に振られるので注意して下さい

抽出条件複数欠けるケース
$ echo "one two three" | sed -r 's/^\s*((one\s*)?(two\s*)?)?(three)?.*$/1: \2\n2: \3\n3: \4/'
1: one 
2: two 
3: three
$ echo "one three" | sed -r 's/^\s*((one\s*)?(two\s*)?)?(three)?.*$/1: \2\n2: \3\n3: \4/'
1: one 
2: 
3: three
$ echo "two three" | sed -r 's/^\s*((one\s*)?(two\s*)?)?(three)?.*$/1: \2\n2: \3\n3: \4/'
1: 
2: two 
3: three
$ echo "one two" | sed -r 's/^\s*((one\s*)?(two\s*)?)?(three)?.*$/1: \2\n2: \3\n3: \4/'
1: one 
2: two
3: 
$ echo "one" | sed -r 's/^\s*((one\s*)?(two\s*)?)?(three)?.*$/1: \2\n2: \3\n3: \4/'
1: one
2: 
3: 
$ echo "two" | sed -r 's/^\s*((one\s*)?(two\s*)?)?(three)?.*$/1: \2\n2: \3\n3: \4/'
1: 
2: two
3: 
$ echo "three" | sed -r 's/^\s*((one\s*)?(two\s*)?)?(three)?.*$/1: \2\n2: \3\n3: \4/'
1: 
2: 
3: three

参考

sedで特定の文字列を抽出 - Qiita
sed/grepコマンドの正規表現 - Miuran Business Systems

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
49