5

私は、好きなテレビ番組のダウンロードされたエピソードのファイル名とフォルダー名をクリーンアップする小さなbashスクリプトを実行しようとしています。彼らはしばしば「[www.Speed.Cd]-Some.Show.S07E14.720p.HDTV.X264-SOMEONE」のように見えます、そして私は基本的にそのspeedcd広告ビットを取り除きたいだけです。

BASHの正規表現マッチングを使用してwww.Speed.Cd、スペース、ダッシュを削除するのは簡単ですが、私の人生では、照合する文字のリストに角かっこを含める方法がわかりません。[-[]は機能しません。また、[-\ []、[-\\ []、[-\\\ []、または削除する括弧の前にある任意の数のエスケープ文字も機能しません。

これが私がこれまでに得たものです:

[[ "$newfile" =~ ^(.*)([- \[]*(www\.torrenting\.com|spastikustv|www\.speed\.cd|moviesp2p\.com)[- \]]*)(.*)$ ]] &&
    newfile="${BASH_REMATCH[1]}${BASH_REMATCH[4]}"

しかし、それは括弧で壊れます。

何か案は?

TIA、ダニエル:)

編集:あなたが疑問に思っている場合に備えて、大文字と小文字を区別しないマッチングを確実にするために「shopt-snocasematch」を使用していることにおそらく注意する必要があります:)

編集2:貢献してくれたすべての人に感謝します。私の発言にはいくつかの問題があったので、どちらの答えが「正しい」答えであるかは100%わかりません。実は、jw013が投稿した質問へのコメントだけが一番正確な答えでしたが、スペースをエスケープする必要があることをまだ理解していなかったので、その時点ではわかりませんでした。私はaefxxを選びました。それは基本的に同じことを言っているのですが、説明付きです:) ormaajの答えにも正しい答えのマークを付けたいと思います。彼は、私の表現にもっと重大な問題を見つけたからです。

とにかく、私が上で使用したアプローチは、不要なものを残して残すためにパーツを一致させて抽出しようとすることは、実際にはあまりエレガントではなく、すべてのケースをキャッチするわけではなく、「Some.Show.S07E14」のような本当に単純なものでもありません.720p.HDTV.X264-誰か-[www.Speed.Cd]"。代わりに、不要な部分だけを一致させて抽出するように書き直してから、元の文字列の文字列を次のように置き換えます(複数のブランドがある場合はループが発生します)。

# Remove common torrent site brandings, including surrounding spaces, brackets, etc.:
while [[ "$newfile" =~ ([[\ {\(-]*(www\.)?(torrentday\.com|torrenting\.com|spastikustv|speed\.cd|moviesp2p\.com|publichd\.org|publichd|scenetime\.com|kingdom-release)[]\ }\)-]*) ]]; do
    newfile=${newfile//"${BASH_REMATCH[1]}"/}
done
4

4 に答える 4

7

オペレーターのことを聞いたのはこれが初めてですが=~、それでも試行錯誤で見つけたものは次のとおりです。

if [[ $newfile =~ ^(.*)([-[:space:][]*(what|ever)[][:space:]-]*)(.*)$ ]] 
                          ^^^^^^^^^^              ^^^^^^^^^^

奇妙に見えますが、実際には機能します(テストしただけです)。


Linuxのマニュアルページregex(7)からの引用を編集します。

リストにリテラル]を含めるには、それを最初の文字にします(可能な^の後に続く)。リテラル-を含めるには、それを範囲の最初または最後の文字、あるいは2番目の端点にします。リテラルaq-aqを範囲の最初のエンドポイントとして使用するには、それを「[」で囲みます。および「。]」を使用して、それを照合要素にします(以下を参照)。これらおよびaq[aqを使用するいくつかの組み合わせ(次の段落を参照)を除いて、aq \ aqを含む他のすべての特殊文字は、角かっこ式内での特別な意味を失います。

于 2012-04-16T22:36:19.220 に答える
4

正規表現を実行しているときはいつでも、テスト式に直接正規表現を配置することのすべての落とし穴を回避できたとしても、変数に正規表現を配置することはBashバージョン間で最も互換性があります。http://mywiki.wooledge.org/BashPitfalls#if_.5B.5B_.24foo_.3D.2BAH4_.27some_RE.27_.5D.5D

現在の正規表現は、オプションで大括弧の前にあるものと一致させようとしているように見えます。たとえば、3と4を次のようなものから実際に保存しようとしていると思います。

$ shopt -s nocasematch
$ newfile='[ www.Speed.Cd ] - Some.Show.S07E14.720p.HDTV.X264-SOMEONE'
$ re='^.*[-[:space:][]*(www\.torrenting\.com|spastikustv|www\.speed\.cd|moviesp2p\.com)[][:space:]-]*(.*)$'
$ [[ $newfile =~ $re ]]
$ declare -p BASH_REMATCH
declare -ar BASH_REMATCH='([0]="[ www.Speed.Cd ] - Some.Show.S07E14.720p.HDTV.X264-SOMEONE" [1]="www.Speed.Cd" [2]="Some.Show.S07E14.720p.HDTV.X264-SOMEONE")'
于 2012-04-16T21:59:10.663 に答える
1

基本的な問題は、明白ではないにしても、非常に単純です。
BASH正規表現は(シェルから)完全に保護されておらず、「二重引用符<strong>」で保護することはできませ。これは、すべてのリテラルスペース(およびタブなど)をbaskslashで保護する必要\があることを意味します...ストーリーの終わり。残りは、ニーズに合わせて正規表現を取得する場合にすぎません。

もう1つ。を使用[\ []して、範囲内の角括弧構成内で それぞれ[]\ ]に一致 させます(この場合はスペースとともに)。 []

例:

newfile="[ ]"
[[ "$newfile" =~ ^[\ []\ []\ ]$ ]] &&
    echo YES ||
    echo NO
于 2012-04-17T00:08:56.510 に答える
0

次のようなことを試すことができます(ただし、フィルタリングしようとしているケースが100%明確ではありませんでした。

newfile="[ www.Speed.Cd ] - Some.Show.S07E14.720p.HDTV.X264-SOMEONE"

if [[ $newfile =~ ^(.*)([^a-zA-Z0-9.]*\[.*\][^a-zA-Z0-9.]*)(.*)$ ]]; then 
    newfile="${BASH_REMATCH[1]}${BASH_REMATCH[3]}"
fi

echo $newfile
# Some.Show.S07E14.720p.HDTV.X264-SOMEONE

の外側の非alnum(およびドット)文字[]、およびその内側のすべての文字を削除するだけです[]

于 2012-04-16T21:36:45.473 に答える