2016-10-04 52 views
0

我有一個文件,users.txt,有喜歡的話,優化sed的多個替代

user1 
user2 
user3 

我想在另一個文件中找到這些話,data.txt和前綴添加到它。 data.txt有近500K行。例如,user1應替換爲New_user1等。我已經寫簡單的shell腳本一樣

for user in `cat users.txt` 
do 
    sed -i 's/'${user}'/New_&/' data.txt 
done 

對於〜1000個字,這個計劃正在分鐘來處理,這讓我吃驚,因爲戰略經濟對話非常快的時候來查找和替換。我試圖參考Optimize shell script for multiple sed replacements,但仍未觀察到太多改善。

有沒有其他方法可以使此過程更快?

回答

2

你可以把你的users.txt成這樣sed命令:

$ sed 's|.*|s/&/New_&/|' users.txt 
s/user1/New_user1/ 
s/user2/New_user2/ 
s/user3/New_user3/ 

然後用它來處理data.txt,無論是由前一個命令的輸出寫入到一箇中間文件,或與進程替換:

sed -f <(sed 's|.*|s/&/New_&/|' users.txt) data.txt 

你的方法遍歷所有的data.txtusers.txt每一行,這使得它緩慢。

如果您無法使用過程中替換,你可以使用

sed 's|.*|s/&/New_&/|' users.txt | sed -f - data.txt 

代替。

+0

感謝您快速回答本傑明:)。我已經嘗試過這種方法,但仍需要將近1分鐘的時間才能完成用戶的1000個條目.txt – user3150037

+1

@ user3150037我不認爲用sed可以獲得更快的速度 - 它仍然必須經歷所有data.txt '並嘗試所有的替代品。更快的方法是找到一個描述'users.txt'中所有單詞的模式,然後你可以只用一個替換。儘管如此,我們不得不爲「users.txt」查看更多的實際數據。 –

+0

users.txt是真實的數據,但有很多條目和data.txt也有類似的數據,但用戶範圍非常高(約500K)。 – user3150037

1

或者..一口氣,我們可以做這樣的事情。讓我們說,我們有一個500k行的數據文件。

$>  
wc -l data.txt 
500001 data.txt 

$>  
ls -lrtha data.txt 
-rw-rw-r--. 1 gaurav gaurav 16M Oct 5 00:25 data.txt 

$> 
head -2 data.txt ; echo ; tail -2 data.txt 
0|This is a test file maybe 
1|This is a test file maybe 

499999|This is a test file maybe 
500000|This is a test file maybe 

讓我們說,我們的users.txt有3-4個關鍵字,這是與「ab_」作爲前綴,在文件「data.txt中」

$>  
cat users.txt 
file 
maybe 
test 

因此,我們要閱讀users.txt併爲每個單詞,我們想要將這個單詞改爲一個新單詞。例如,「文件」爲「ab_file」,「也許」爲「ab_maybe」。

我們可以運行一個while循環,讀取要逐個添加前綴的輸入單詞,然後運行perl命令將輸入字存儲在變量中的文件上。在下面的例子中,讀取字作爲$ word傳遞給perl命令。

我定時執行此任務,並且發生得相當快。是否在我的Windows 10上託管的VM上(使用Centos7)。

time cat users.txt |while read word; do perl -pi -e "s/${word}/ab_${word}/g" data.txt; done   
real 0m1.973s 
user 0m1.846s 
sys  0m0.127s 
$>  
head -2 data.txt ; echo ; tail -2 data.txt 
0|This is a ab_test ab_file ab_maybe 
1|This is a ab_test ab_file ab_maybe 

499999|This is a ab_test ab_file ab_maybe 
500000|This is a ab_test ab_file ab_maybe 

在上面的代碼中,我們讀到了一句話:測試,文件,也許在data.txt文件改成了ab_test,ab_file,ab_maybe。頭部和尾部計數確認我們的操作。

歡呼聲, 拉夫

+0

你的格式化讓你很難理解你的答案。 – blackpen

+0

嗨,我很抱歉。我希望能改善這一點。這是我作爲一個正確的用戶在stackoverflow網站上的第一天。我正在學。感謝您的評論。 現在,我刪除了額外的粗體字體。還有什麼建議? Gaurav – User9102d82

+0

歡迎來到SO!有家的感覺。 – blackpen

2

桑達被稱爲是非常快的(可能比C僅更糟)。

而不是sed 's/X/Y/g' input.txt,請嘗試sed '/X/ s/X/Y/g' input.txt。後者已知速度更快。

既然你只有一個「在一個時間語義一條線」,你可以用parallel運行(多核心CPU-S)是這樣的:

cat huge-file.txt | parallel --pipe sed -e '/xxx/ s/xxx/yyy/g' 

如果使用純ASCII工作文件,你可以通過使用「C」語言環境加速它:

LC_ALL=C sed -i -e '/xxx/ s/xxx/yyy/g' huge-file.txt 
+0

謝謝你的答案。它真的幫助:) – user3150037