2012-04-16 182 views
5

我試圖做一個很小的bash腳本,將清理下載發作的文件和文件夾名的一些電視節目,我喜歡。他們經常看起來像「[www.Speed.Cd] - Some.Show.S07E14.720p.HDTV.X264-一個人」,我基本上只是想去掉那個speedcd廣告位。BASH正則表達式匹配 - 包括方括號中的括號以匹配?

使用BASH中的正則表達式匹配很容易移除www.Speed.Cd,空格和破折號,但在我的生活中,我無法弄清楚如何將括號包含在要匹配的字符列表中。 [ - []不起作用,既不確實[ - \ [],[ - \\ [],[ - \\\ [],或我想刪除托架前述任意數量的轉義字符。

這裏是我到目前爲止有:

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

但它打破的支架。

任何想法?

TIA, 丹尼爾:)

編輯:我也許應該注意到,我使用「禁用了javascript -s nocasematch」,以確保不區分大小寫的匹配,以防萬一你想知道:)

編輯2:感謝所有人的貢獻。我不能100%確定哪個答案是「正確的」,因爲我的發言有幾個問題。其實最準確的答案只是我的問題發表jw013評論,但我並沒有在當時得到它,因爲我還沒有明白過來,空間應該逃脫。我選擇了aefxx的作爲一個基本上說是相同的,但解釋:)會一直喜歡把一個正確的答案標記上ormaaj的回答,也因爲他發現我的表達更嚴重的問題。

無論如何,我在上面使用的方法,試圖匹配和提取要保留並留下不需要的部分的部分實際上不是非常優雅,並且不會捕獲所有情況,甚至不會像「某些.Show.S07E14.720p.HDTV.X264-SOMEONE - [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 
+0

代替'[ - \ []''試試[ - \ []'和'而不是[ - \]''試試[] - \]'。 – jw013 2012-04-16 21:30:38

+0

謝謝,但沒有甜甜圈:( 對這些的任何想法?AFAICT,第一個逃避空間,至於第二個,BASH指南指出,當使用破折號作爲文字(而不是指定一個範圍),它必須以第一個字符的形式出現? – DanielSmedegaardBuus 2012-04-16 21:37:15

回答

7

好吧,這是我第一次聽說過=~運營商的但仍然這裏是我發現試驗和錯誤:

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

看起來很奇怪,但實際上確實有效(剛測試過)。

編輯
從Linux手冊頁的正則表達式(7)報價:

To include a literal ] in the list, make it the first character (following a possible ^). To include a literal -, make it the first or last character, or the second endpoint of a range. To use a literal aq-aq as the first endpoint of a range, enclose it in "[." and ".]" to make it a collating element (see below). With the exception of these and some combinations using aq[aq (see next paragraphs), all other special characters, including aq\aq, lose their special significance within a bracket expression.

+0

的確,我忘了那個伎倆。這是在Linux手冊頁的正則表達式(7)的前幾段中提到的。 – ormaaj 2012-04-16 22:43:22

+0

這一個正確匹配右括號,包括它周圍的所有空格和破折號!謝謝!儘管如此,仍然有第一個submatch吃開始括號,但這不是問題:) – DanielSmedegaardBuus 2012-04-16 22:48:20

+0

哦,我沒有打擾子模式,因爲我認爲真正的問題是(看似)不可能逃脫那些括號。 – aefxx 2012-04-16 22:50:48

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 

它只是剝內[]

+0

@DanielSmedegaardBuus:我所指定的字符的唯一範圍是那些**不是有效的。它的開放程度遠遠大於您對硬編碼網站的URL – jdi 2012-04-16 21:51:21

+0

對不起,@ jdi,我錯過了你的觀點,但是我特意試圖去掉這個特定符號中的特定網址,甚至當你的建議適用於這種特殊情況時,它只是刪除括號內的任何內容,並且可能真的被減少到「[[$ newfile =〜^(。*)(\\ [。* \\])(。*)$]]」AFAICT。 – DanielSmedegaardBuus 2012-04-16 22:01:52

+0

@DanielSmedegaardBuus:AFAICT它們不匹配,請考慮「Some stuff這裏 - [www。 Speed.Cd] - Some.Show.S07E14.720p.HDTV.X264-SOMEONE「 – jdi 2012-04-16 22:11:04

4

任何非alnum(和點)的[]以外的字符,以及任何每當你做一個re gex它是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")' 
+0

實際上,因爲我啓用了不區分大小寫的匹配,主要問題似乎是我在子模式2中的「零個或多個實例」星號,所以第一個子模式會吃得比它應該多(因爲沒有起始括號未使用仍然使子模式二有效)。你的建議避免了這一點。 – DanielSmedegaardBuus 2012-04-16 22:42:26

+0

我正在考慮做同樣的事情,即匹配任何不是子模式1的起始括號,但希望是「更通用」,並不要求括號在那裏,因爲有時他們只會放入「 - 一些」。 tracker.org「在最後或whatnot。但嚴重的是,這是一個我必須忍受的角落案例:) OTOH,我仍然不知道爲什麼應該吃右托架和周圍空間和/或破折號的圖案不能吃掉它所有,無論是在我的代碼還是在你的(即[4] =「 - Some.Show.S07E14.720p.HDTV.X264-有人,我不想有領先的」 - 「) – DanielSmedegaardBuus 2012-04-16 22:43:28

+0

我是現在就工作,但如果你發現它,請讓我知道;)謝謝! – DanielSmedegaardBuus 2012-04-16 22:44:04

1

基本問題是很簡單,如果不是很明顯。
一個bash正則表達式是完全未受保護的(來自殼),並且不能由雙引號保護。這意味着每隔字面空間(和標籤等)必須受到baskslash \保護...故事結束。其餘的只是讓你正則表達式來滿足你的需求。

另一件事;使用[\ [][]\ ]以分別匹配[],在範圍方括號構造(在這種情況下連同空格)範圍內。

例如:

newfile="[ ]" 
[[ "$newfile" =~ ^[\ []\ []\ ]$ ]] && 
    echo YES || 
    echo NO 
相關問題