単一のコマンドは、2つの文字列を使用して2つの文字列の間の文字列を抽出します(例:「tr」(式なし))

単一のコマンドは、2つの文字列を使用して2つの文字列の間の文字列を抽出します(例:「tr」(式なし))

見たここsed を使用して、1 行の別の 2 つの文字列間のテキストを取得する方法。たとえば、次のようになります。

sed 's/.*starting_text\(.*\)ending_text.*/\1/'

trしかし、2つの文字列だけを使用して、最初の文字列の前または2番目の文字列の後のすべての項目を切り取る単純なコマンド(たとえば、文字列抽出の場合)が必要です。

grep something some_file | between message\"\:\" " with"

そしてエスケープ文字を処理します。

答え1

区切り文字が1行に複数回表示される場合は、代わりに次のようにPerlを使用できます。

between() {
  perl -Tlne 'BEGIN{$b=shift;$e=shift}
             print for /\Q$b\E(.*?)\Q$e\E/g' "$@"
}

たとえば、次のようになります。

$ echo "[b]test[e] foo [b]bar[e]" | between '[b]' '[e]'
test
bar

次のように使用することもできます。

between BEG END file1 file2...

答え2

通常、sedでこれを行うには、私が見つけた部分文字列を見つけるために使用される正規表現でエスケープ文字が必要です。ここ(注:追加情報ここ問題がある場合)。

次に、関数にパイプする方法を見つけました。ここ

これらすべてをmyで利用可能な関数にまとめると、.bashrc次のようになります(a変数とb変数を設定する必要はありませんが、読みやすくなります)。

between(){
  a=$(printf '%s\n' "$1"|sed 's![\*.^$/[]!\\&!g')
  b=$(printf '%s\n' "$2"|sed 's![\*.^$/[]!\\&!g')
  sed "s/.*$a\(.*\)$b.*/\1/"
}

Joseph R.が述べたように、この回答grep -oP を使用して同様の操作を実行する方法を示します。 Perl準拠の正規表現をエスケープするには、次のことがわかりました。これしたがって、次のように動作することができます。

between(){
  a=$(printf '%s\n' "$1"|sed 's![]\*.^+?(){|$[]!\\&!g')
  b=$(printf '%s\n' "$2"|sed 's![]\*.^+?(){|$[]!\\&!g')
  grep -oP "(?=$a).*?(?=$b)"
}

関連情報