文字列を検索し、次の文字が表示されるまで削除します。

文字列を検索し、次の文字が表示されるまで削除します。

文字列1:svn+ssh://[email protected]/repo-2015/branches/DEV_BRANCH_21/main/code/main_input.c

出力が必要:main/code/main_input.c

文字列2:svn+ssh://[email protected]/repo-2015/branches/TEST_BRANCH_56/main/code/main_output.c

出力が必要:main/code/main_output.c

これを試しました。

echo "svn+ssh://[email protected]/repo 2015/branches/DEV_BRANCH_21/main/code/main_input.c" | sed -e 's/^.*\(branches\/\)//g'

四半期後、次の「/」をどのように進めて削除するのかわかりません。

答え1

$ echo "svn+ssh://[email protected]/repo 2015/branches/DEV_BRANCH_21/main/code/main_input.c" | grep -oP 'branches/.*?/\K.*'
main/code/main_input.c

$ echo "svn+ssh://[email protected]/repo-2015/branches/TEST_BRANCH_56/main/code/main_output.c" | grep -oP 'branches/.*?/\K.*'
main/code/main_output.c

そしてsed

sed 's|.*branches/[^/]*/||'
  • [^/]*以外のテキストと一致します。/

答え2

POSIX シェルモードストリッピング演算子を使用します。

string=svn+ssh://srv.com/repo/branches/TEST_BRANCH_56/main/code/main_output.c
output=${string#*/branches/*/}

$stringこれにより、パターンに一致する最小の先行部分が除去されます。以下とは異なります。

printf '%s\n' "$string" | sed '
  :1
  $!{
   N;b1
  }
  s|.*/branches/[^/]*/||'

または:

expr " $string" : ' .*/branches/[^/]*/\(.*\)'

この場合、string=foo/branches/bar/branches/baz/whatever1つは${string#pattern}返されbranches/baz/whatever、もう1つは返されますwhatever

答え3

私は次のようにgrepを使います:

echo "svn+ssh://[email protected]/repo 2015/branches/DEV_BRANCH_21/main/code/main_input.c" | grep -Eo "main\/code.*"

答え4

awk 正規表現を使わずに簡単な方法:

$ awk '{print substr($0,match($0,/main/));}' input.txt                                                                   
main/code/main_input.c
main/code/main_output.c

関連情報