2012-10-20 89 views
0

我試圖寫一個bash腳本使用sed來刪除文件的一些行。行號以相反的順序存儲在另一個文件中。 我試圖做的命令如下:bash腳本使用sed將刪除特定行不起作用

sed -e '{lineNumber}d' ./file.txt 

這是我有這麼遠,但它不工作

while read -r line 
do 
    sed -e "/${line}d" ./file.txt 
done < ./lineNum.txt 

我收到以下錯誤:
的sed:-e表達#1,燒焦4:未結束地址的正則表達式

+0

所以你已經列出了需要的線2號文件,從第一個文件被刪除? –

+0

謝謝。該腳本正在工作,但不會刪除線條。我使用sed命令是否錯誤? – MFK

+0

@ sampson-chen是的 – MFK

回答

1
while read -r line; do sed -i "${line} d" ./file.txt; done < ./linenum.txt 

這工作(我認爲你的問題是使用-e);但效率不高。一次傳遞多行可能更好,以避免每行讀寫一次文件。例如,您可以將linenum.txt轉換爲「6 d; 2 d; 1 d」等內容然後將其傳遞給sed進行一次處理。

+0

它的工作原理!非常感謝。並感謝提高效率的建議,我將以該格式轉換文件! – MFK

1

您可以直接使用sed沒有使用循環的變化:

sed 's/.*/&d/' lineNum.txt | sed -i -f - file.txt 
+1

不錯的再版。在此基礎上,我想也表明'sed的-n '/^[0-9][0-9]*$/{s/.*/ &d/; p}' lineNum.txt | SED -i -f - file.txt'避免與LINENUM壞格式化線問題(特別是空行這將產生一個精簡「d」,並刪除所有文件內容) –

+0

@GermanGarcia:尼斯趕上!但我期望'sed -n'/^[0-9] [0-9] * $/{s/$/d /; p}'lineNum.txt | SED -i -f - file.txt'是更有效和(猜測)'的sed -n '/^[0-9] [0-9] * $ /秒/ $/d/P' lineNum.txt | sed -i -f -file.txt'用較少的代碼做同樣的事情。也只是出於好奇:如果一個數字以前導零開始,或者一行只包含零,會發生什麼? '[1-9] [0-9] *會更強大嗎? – mschilli

3

事實上你做錯了什麼是這個

sed -e "/${line}d" ./file.txt 

你看,sed有這句法

sed -e "/REGEX/d" ./file.txt 

其中刪除包含匹配(ES)爲0的所有行模式。由於你有第一個/,sed認爲你正在嘗試使用正則表達式匹配,因此它的意思是unterminated address regex

需要被簡單地刪除違規反斜槓最小修復,即

sed -e "${line}d" ./file.txt 

除了:不是sed解決像OP要求,但做什麼OP更有效地希望。

awk 'NR==FNR {arr[$0]++; next} {if (!arr[FNR]) print }' linenum.txt file.txt 
+1

代替'{(!ARR [FNR])如果打印}'的,你可以寫:'(FNR在ARR)'。這是一個小巧整潔。 HTH。 – Steve

+1

良好的通話。我甚至可以簡單地使用'!arr [FNR]',但是我認爲'!(arr中的FNR)'更好,因爲如果它之前不存在,它不會創建該元素。 – doubleDown

2

只要有不悍然多行被刪除,你是不是用的sed(在同一時間,sed在HP-UX僅限於有關遠遠限量版本工作的系統上100個指令),那麼你可以使用:

sed 's/$/d/' linenum.txt | sed -f - file.txt 

這將使用第一sed的行號轉換成刪除命令(請注意你的麻煩的部分是一個流浪不必要的斜槓),然後告訴第二sed閱讀從標準輸入(-f -)的腳本,並把它應用到file.txt

上述工作與GNU sed;它不適用於Mac OS X 10.7.5上的BSD sedsed: -: No such file or directory)。在您的系統上使用它之前對其進行測試。

當然,如果您有足夠的最新版本bash(適用於bash 4.2但不適用於3。2),那麼你可以使用「進程替換」來解決的sed限制:

sed -f <(sed 's/$/d/' linenum.txt) file.txt 

如果這也不行,你可以第一sed命令的輸出寫入到一個文件,然後使用該(臨時)文件作爲sed腳本的名稱。所以,有很多方法可以做到這一點。然而,任何超過3個進程(的sed兩分和一個rm)是奢侈的。如果你只需要做一次,這可能不是一個問題,但如果你一分鐘要做很多次,這可能是一個問題。

+0

只是猜測,但我認爲'sed: - :沒有這樣的文件或目錄問題也可以通過使用'/ dev/stdin'來解決。由於我不在Mac上,因此無法嘗試。 – mschilli