sedを使用して、末尾の最初の出現で停止する部分文字列を抽出します。

sedを使用して、末尾の最初の出現で停止する部分文字列を抽出します。

文字列から部分文字列を抽出したいのですが、正規表現の末尾が繰り返されています。多くの言語の instr() 関数が最初のインスタンスを返すのと同じように、正規表現の末尾の最初のインスタンスで sed を停止したいと思います。例:

echo "This is a test some stuff I want string junk string end" | sed -n 's/.*\(.te.*ng\).*/\1/p' 
returns: test some stuff I want string junk string
I want to return: test some stuff I want string

答え1

グレップアプローチ(必要ペクレサポート):

s="This is a test some stuff I want string junk string end"
grep -Po 'te.*?ng' <<< $s

代替パールアプローチ:

perl -ne 'print "$&\n" if /te.*?ng/' <<< $s

出力(両方のアプローチの場合):

test some stuff I want string

  • .*?-?ここは貪欲でない修飾子は、一致するように指示しますミニマルファッション

答え2

2 つの手順で実行します。まずプレフィックスを削除し (プレフィックスにターミネータが存在する場合)、次にプレフィックスの後のすべてを削除します。T一致しない場合は、コマンドを使用して行をスキップします。

echo "This is a test some stuff I want string junk string end" |
sed -n 's/.*\(.te.*ng\)/\1/; T; s/\(ng\).*/\1/p'

または、一致しない行を最初に削除してから、都合のよいときに置換を実行します。

echo "This is a test some stuff I want string junk string end" |
sed '/.*\(.te.*ng\)/!d; s/.*\(.te.*ng\)/\1/; s/\(ng\).*/\1/'

または、一致する行に対してのみ置換と最終印刷を実行します。

echo "This is a test some stuff I want string junk string end" |
sed '/.*\(.te.*ng\)/ { s/.*\(.te.*ng\)/\1/; s/\(ng\).*/\1/p; }'

答え3

あなたの場合はカットコマンドを使用することをお勧めします

echo "I am a useful and I am a string. Did I mention that I'm a string?" | cut -d "string" -f1

これにより、文字列が 3 つの部分 (最初の部分の前、2 番目の部分の後、および '文字列' の間) にカットされます。-d"" を使用すると、カッターとして使用するパターンを選択でき、-fNumber を使用すると、取得する部分を選択できます。問題: '文字列' が削除されます。解決策:

String=`echo "I am a useful and I am a string. Did I mention that I'm a string?" | cut -d "string" -f1`
String="$(String) string"
echo $String

削除された区切り文字「文字列」を、出力で定義された$String変数の末尾に追加します。

答え4

# 貪欲な一致を実行する方法: POSIX sed を使用して「test .*? string」

sed -e '
   /test.*string/!d;      # non-interesting line
   /^test/s/string/&\
/;                        # append marker after the first substring "string"
   /\n/{P;d;}             # initial portion of pattern space is our result
   s/test/\
&/;D;                     # remove portion before the substring "test"
' yourfile

別のPOSIX-リーこの方法は、パターン スペースの末尾から部分文字列 "string" を 1 つずつ取り除き、残りが 1 つだけになるまで (部分文字列 "test" の後) 続けます。次に、残った部分文字列 "test" を先頭に移動します。

sed -e '
   :loop
      s/\(test.*string\).*string.*/\1/
   tloop
   /^test/!s/test/\
&/;/\n/D
' yourfile

関連情報