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

grep方法(要求ポリメラーゼ連鎖反応サポートする):

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

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

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

関連情報