Sedを使用して、URLのクエリ文字列にある多くのキーと値のペアの1つの値の部分を抽出しようとしています
これは私が試していることです:
_echo 'http://www.youtube.com/watch?v=abc&g=xyz' | sed 's@^https?://(www.)?youtube.com/(watch\\?)?.*?v(=|/)([a-zA-Z0-9\-_]*)(&.*)?$@$4@'
_
ただし、常に入力URLをそのまま出力します。
何が悪いのですか?
更新1
いくつかの問題を明確にするために:
sed
のバージョンを見つけることができませんでしたが、Mac OS X(10.7.5)に付属しているバージョンです。sed
$ 1、$ 2などは一致するようですが、\ 1、\ 2などはエラーを出します:sed: 1: "s@^https?://(www.)?yout ...": \4 not defined in the RE
- 不正解です!後でわかりました。混乱を招きましたことをお詫び申し上げます。更新2
以下の@slhckの提案に基づいてsed
REをより具体的にするために更新しましたが、問題は以前と同じままです。
更新
このバージョンのman
のsed
ページに基づいて、これはBSD風味のバージョンであると思われます。
abc
だけが必要な場合はさらに簡単です:
echo 'http://www.youtube.com/watch?v=abc&g=xyz' | awk -F'[=&]' '{print $2}'
xyz
が必要な場合:
echo 'http://www.youtube.com/watch?v=abc&g=xyz' | awk -F'[=&]' '{print $4}'
説明:
awk
:入力ファイルを1行ずつ自動的に処理し、各行をフィールドに分割するスクリプト言語です。したがって、awk
を使用してファイルを処理する場合、各行の最初のフィールドは$1
、2番目のフィールドは$2
など、$N
までです。デフォルトでは、awk
はフィールド区切り文字として空白を使用します。
-F'[=&]'
:-F
は、フィールド区切り文字をスペースから別のものに変更するために使用されます。この場合、私はそれに class の文字を与えています。大括弧([ ]
)は、多くの言語で文字のグループを示すために使用されます。したがって、具体的には、-F'[=&]'
は、awk
が&
と=
の両方をフィールド区切り文字として使用する必要があることを意味します。
したがって、&
と=
を区切り文字として使用して、質問からの入力文字列を指定すると、awk
は次のフィールドを読み取ります:
http://www.youtube.com/watch?v=abc&g=xyz
|----------- $1 -------------| --- - ---
| | |
| | ̣----- $4
| -------- $3
----------- $2
だから、あなたがしなければならないすべてはあなたが望むものを印刷することです{print $4}
。
また、文字列が有効なYouTube URLであることを確認する必要があると言いましたが、sed
を使用してそれを行うことはできません。単に行全体を印刷します。 Perl
のようなツールを使用して、正規表現が一致する場合にのみ印刷することができます:
echo 'http://www.youtube.com/watch?v=abc&g=xyz' |
Perl -ne 's/http.*www.youtube.com\/watch\?v=(.+?)&.+/$1/ && print'
最後に、単純にabc
を印刷するには、標準のUNIXツールを使用できます cut
:
echo 'http://www.youtube.com/watch?v=abc&g=xyz' |
cut -d '=' -f 2 | cut -d '&' -f 1
「xyz」が必要な場合は、これを試してください(GNU sed):
echo 'http://www.youtube.com/watch?v=abc&g=xyz' | sed 's/.*=\([[:alnum:]]*\).*/\1/'
@Endoroと@slhckによって与えられた回答に基づいてsed
を試してみると、最終的な回答(私が欲しかったもの)に私を導きました。これは、Mac OS X(10.7.5)上のsed
のバージョンで私にとってうまくいくものです:
_echo 'http://www.youtube.com/watch?v=dnCkNz_xrpg' | sed -E 's@https?://(www\.)?youtube.com/(watch\?).*v=([-_a-zA-Z0-9]*).*@\3@'
_
説明:
-E
_はsed
に拡張REを使用させるためのものです。 sed
の他のバージョンでは、_-r
_が同等のオプションになる場合があります。https?://(www\.)?example.com/(.*\?).*key=([^&]*).*
)\3
_は、括弧内の3番目の式に一致し、それを回答/一致として出力します(これは私が望んでいることです)。\
_)をエスケープする必要がないようにします。私が助けられたことで、これが他の人にも役立つことを願っています。
本当に動画IDだけが必要な場合– v=
と次の&
の間のすべて–使用するだけです。
sed -r 's/.*v=([[:alnum:]]*).*/\1/'
あなたのコマンドのどこが悪いのですか?
拡張正規表現を使用するには、-r
が必要です。省略した場合、sed
は括弧を文字どおりに解釈するため、一致グループはありません。 BSD sed
では、代わりに-E
オプションを使用してください。
一致を参照するには$1
を使用しますが、\1
を使用する必要があります。 $1
は、実際には、たとえば現在のスクリプトに渡されるシェル引数です。
パラメータ値と一致させるには、[[:alnum:]]
(またはIDの設定方法によっては[a-zA-Z0-9_]
)などの文字クラスを使用する必要があります。そうしないと、次の&
もキャプチャされます。正規表現は貪欲であり、abc&g=xyz
を使用する場合は.*?
に一致します。遅延定量化はBRE/EREではサポートされておらず、Perl正規表現またはその他の「モダン」フレーバーでのみサポートされているためです。
SEDが一致しないため、常にURLが表示されます。
echo 'http://www.youtube.com/watch?v=abc&g=xyz' | sed 's!^http://www.youtube.com/watch\?\(.*=.*\)&\(.*=.*\)!\1!'
V = abcを表示します