サイトの名前を取得する乱雑なスクリプトがあります ( など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"