2015-02-05 22 views
1

我寫了一個簡單的shell腳本,可以工作,但效率非常低。在較大的文件上運行需要很長時間。我正在尋找更快的解決方案。查找並從列表(或其他文件)中找到並替換匹配的多個參數

樣品輸入文件:

data.csv

1,data,data 
3,data,data 
4,data,data 
9,data,data 
... 

matches.txt

3 
9 
16 
17 
... 

腳本我的每個項目寫道迭代中matches.txt。它使用sed來匹配csv文件中的行的開頭,並通過預先加上**進行註釋。

#!/bin/bash 

IFS=$'\r\n' GLOBIGNORE='*' :; XYZ=$(<matches.txt) 
for id in ${XYZ[@]} 
do 
    sed -i '' "${id}s/^**//" data.csv 
done 

我使用OS X所以sed參數稍有不同。

回答

3

而不是在循環中調用sed您可以使用此AWK:

awk -F ',' 'FNR==NR{a[$1]++; next} $1 in a{$0 = "**" $0} 1' matches.txt data.csv 
1,data,data 
**3,data,data 
4,data,data 
**9,data,data 

要保存awk輸出:

awk -F ',' 'FNR==NR{a[$1]++; next} $1 in a{$0 = "**" $0} 1' matches.txt data.csv > _tmp 
mv _tmp data.csv 

說明:

  • -F ',' - 使用字段分隔符作爲逗號
  • FNR==NR - 執行該程序段的第一個文件
  • {a[$1]++; next} - 創建密鑰數組作爲$1從第一文件和移動到下一行
  • $1 in a{$0 = "**" $0} - 對於第二文件,如果第一字段是在陣列a然後在當前行中加上**
  • 1 - 默認awk動作(打印行)
+0

哇!好吧,找到線路要快得多,但是,我需要修改原始文件。我正在使用的命令執行就地修訂。有沒有類似的'awk'?你能解釋一下命令嗎? – 2015-02-05 19:18:35

+0

我在回答中添加了詳細信息,也是保存輸出的一種方法。 – anubhava 2015-02-05 19:28:38

+0

如果您使用'gnu-awk> 4.1.0',那麼您可以使用:'awk -i inplace -F',''FNR == NR {a [$ 1] ++;下一個}在{print'**「$ 0}'matches.txt data.csv中獲得$ 1' – anubhava 2015-02-05 19:31:01