2012-06-15 46 views
1

我知道這對你們其中一位專家來說真的很容易!Bash腳本修復域名列表

我有一個這樣的名單:

www.google.com 
ebay.com 
yahoo.com 
www.bing.com 
www.buy.com 
woot.com 
news.google.com 
images.google.com 

我試圖寫一個bash/SED/awk腳本來清理這個名單。 我需要的列表看起來像這樣:

www.google.com 
www.ebay.com 
www.yahoo.com 
www.bing.com 
www.buy.com 
www.woot.com 
news.google.com 
images.google.com 

在它需要添加摘要「WWW」。如果它還沒有www或一個子域。該列表位於名爲theList的文件中。我跛腳的嘗試是這樣的:

sed 's/^www\./' theList > cleanedList 

這顯然不適合在那裏已經有WWW或子域的情況下工作。 任何想法,將不勝感激。

謝謝!

EV

+2

你用'foo.co.uk'做什麼?它需要一個'www',但你怎麼知道? –

+0

@DennisWilliamson這是一個有效的問題,但它不是語料庫的一部分。這就是爲什麼我發表了很多意見徵詢的原因:並非每個解決方案都需要涵蓋每個用例。有時候「快速和骯髒」是足夠好的。 :) –

+1

@CodeGnome:沒錯,沒有列出這樣的例子。但是,*我們*不知道實際數據中是否可能存在類似的數據。這就是爲什麼*我*發表評論詢問它。這可能是因爲OP沒有意識到解析域名是一個難題,因此沒有想到發佈更多的例子。 –

回答

1

awk比sed容易得多。例如:

awk -F. 'NF == 2 {print "www." $0; next}; {print}' theList > cleanedList 

這將「子域名」定義爲名稱中小於兩個點的任何內容,並將點用作每個記錄中的字段分隔符。你當然可以調整,以適應。

它能夠正確處理所提供的語料,你可以在這裏看到:

$ cat cleanedList 
www.google.com 
www.ebay.com 
www.yahoo.com 
www.bing.com 
www.buy.com 
www.woot.com 
news.google.com 
images.google.com 
+0

嗯......看起來不錯,除了它將www放在有子域的域(即news.google.com和images.google.com)上。 – exvance

+0

@ user548971好點;無論如何,我認爲我的awk解決方案更清潔。希望能幫助到你。 –

+0

可以縮寫爲'awk -F。 'NF == 2 {print「www。」 $ 0; next} 1'theList' –

1

在bash,你可以這樣寫:

while read; do 
    case "$REPLY" in 
    www.*|*.*.*)   # begins with www. or contains at least two dots... 
    echo "$REPLY"  # ...leave as-is 
    ;; 
    *)     # all other cases... 
    echo "www.$REPLY" # ...prepend "www." 
    ;; 
    esac 
done <theList> cleanedList 

外while循環從標準輸入讀取(重定向到theList在最後一行),一次一行。如果沒有其他參數,則該行將在shell變量$REPLY中結束。

case語句與C的switch語句類似,但它與通配符模式(而不是整型常量)進行比較。我們使用它來將行($REPLY)分爲兩類:一類不需要www.前置,另一類不需要。

的第一圖案(www.|*.*.*))實際上是兩個選擇:要麼線匹配www.*(即www.開始。),或者它匹配*.*.*(即它至少包含兩個點(他們可能是相鄰的,但這何嘗不是。一個模式來驗證模板名稱),因爲在Unix中的*也匹配. s)。在這種情況下,我們只是輸出這條線。

第二種模式(*))匹配所有內容,但只有在第一種模式不匹配時纔會選擇。在這些情況下,我們輸出"www.$REPLY",即。我們將www.添加到剛剛閱讀的行中。

他們一起實現你描述的算法。

1

關鍵在the regex。它捕獲所有沒有子域的獨立域,然後用www.和它自己替換它。

sed -ri 's/^([^.]+\.[^.]+)$/www.\1/' YOUR_FILENAME 

或者:

sed -r 's/^([^.]+\.[^.]+)$/www.\1/' YOUR_FILENAME > NEW_FILENAME 
+0

爲什麼從正則表達式的第二部分中排除'$'s?記住正則表達式的LHS可以用'&引用,所以'sed'/^[^.]*\.[^.]*$/ www。&/''也可以工作並且不太忙。 – potong

+0

我不明白你爲什麼要把'[^。]'作爲可選項('*')。它應該至少有1個或更多(甚至可能是2個,我從來沒有看到有1個字符的域)。你有什麼理由希望我不排除'$'?你挑剔挑剔嗎? – ohaal

+0

在'['和']'之間,'.'代表一個點,'$'代表一美元。在類的結構之外,「。」表示任何字符,「$」表示字符串的結尾。所以'[^。$]'是指除點或美元之外的任何字符,這是你的意圖嗎? – potong