スクリプトにエラーが見つかりました

スクリプトにエラーが見つかりました

サイトの名前を取得する乱雑なスクリプトがあります ( などhttps://google.com/etc)。

#!/bin/bash

ARTIST=$(echo "$@" | grep -oP 'https:\\/\\/\\K.+?(?=.com)' | sed -e "s/\b\(.\)/\u\1/g")

echo $(echo "$@" | grep -oP 'https:\\/\\/\\K.+?(?=.com)' | sed -e "s/\b\(.\)/\u\1/g")
echo "$ARTIST"

echo "$@"

そして、何らかの理由で、$(...)スクリプトの外部で実行している間は何も返されず、正常に動作します。

$ ./test.sh https://nothing.bandcamp.com/music   
https://nothing.bandcamp.com/music 

予想される行動:

$ echo "https://nothing.bandcamp.com/music" | grep -oP 'https:\\/\\/\\K.+?(?=.com)' | sed -e "s/\b\(.\)/\u\1/g" 
Nothing.Bandcamp

何が間違っているのでしょうか?

答え1

正規表現\で自分自身をエスケープしています。つまり、 はリテラルのバックスラッシュの後にスラッシュが続くことを意味し、 はリテラルのバックスラッシュの後に大文字の K が続くことを意味します。grep\\/\\K

また、/を でエスケープする必要もありませんgrep。これは、/を正規表現の区切り文字として使用する場合にのみ必要です。デフォルトはsedまたは です(通常は、または、 または などperlの別の区切り文字を使用する方が適切です)。,:=

代わりに、エスケープされていない単純な/, およびを使用します\K。例:

#!/bin/bash
ARTIST=$(echo "$@" | grep -oP 'https://\K.+?(?=.com)' | sed -e 's/\b\(.\)/\u\1/g')
echo "$ARTIST"

サンプル出力:

$ ./test.sh https://nothing.bandcamp.com/music   
Nothing.Bandcamp

$ echo "https://nothing.bandcamp.com/music" | grep -oP 'https://\K.+?(?=.com)' | sed -e 's/\b\(.\)/\u\1/g'
Nothing.Bandcamp

注: これは、スクリプトで実行する場合と同様に、コマンド ラインで実行する場合にも当てはまります。

例えば、次のコードは出力なしスクリプトの場合と同じです。

$ echo "https://nothing.bandcamp.com/music" | grep -oP 'https:\\/\\/\\K.+?(?=.com)' | sed -e "s/\b\(.\)/\u\1/g"

関連情報