2014-03-07 46 views
2

我有兩個文件,一個數據文件和一個查找文件。所述數據文件的Shell腳本 - 在第二個文件中使用lookup進行智能替換

一個場必須由一個值,它可以在查找文件中找到被改變。

的數據文件看起來像:

2013-04-24;1;0.1635;1.4135 
2013-04-24;1;0.9135;1.4135 
2013-04-24;2;0.9135;1.4135 

查找文件看起來像:

1;2ab1e4c0-de4d-11e2-a934-0f0479162b1b 
2;2ab21e90-de4d-11e2-9ce8-d368d9512bad 
3;2ab2582e-de4d-11e2-bb5f-6b1f6c4437f8 

的結果必然是:

2013-04-24 2ab1e4c0-de4d-11e2-a934-0f0479162b1b 0.1635 1.4135 
2013-04-24 2ab1e4c0-de4d-11e2-a934-0f0479162b1b 0.9135 1.4135 
2013-04-24 2ab21e90-de4d-11e2-9ce8-d368d9512bad 0.9135 1.4135 

我知道如何使用awk來讀取數據文件並轉換字段分隔符。

awk 'BEGIN { FS = ";"; OFS = " " } ; 
     { print $1, $2, #3, $4 }' $1 > $1.updated 

但我不知道一個聰明的方法來在shell腳本的查找文件中查找變量$ 2,並用UUID替換原始值。

查找文件將永遠不會很大,在極端情況下最多會有1000條記錄。

在bash或perl中的任何解決方案也將不勝感激。

+0

只是供參考,你的結果是不正確的。您的數據文件具有'2'作爲第三行,由查找文件中的'3'值替換。 –

+0

你說得對。我編輯過,不會讓更多的讀者感到困惑。 – j3pinter

回答

3

這應該爲你工作:

awk -F';' 'NR==FNR{a[$1]=$2;next}{$2=a[$2]}1' lookup data 
  • 設置輸入字段分隔符通過查找文件;
  • 運行,與第1列的鍵創建陣列a並存儲第2列作爲值
  • 一旦查找文件被加載到內存中,用數組值替換數據文件的第二列。
+0

謝謝!這非常有幫助。我知道awk功能非常強大,但這是非常小的代碼。大! – j3pinter

0

awk具有「陣列」(實際上像哈希/字典一樣運作),對此非常有效。

awk 'BEGIN { FS = ";"; OFS = " " } 
    { 
     if (NR == FNR) 
      values[$1] = $2 
     else 
      print $1, values[$2], $3, $4 
    }' lookup data 
+0

在軟件中測試一個條件是不好的做法(例如'NR == FNR'),然後測試相同條件的否定('NR!= FNR')。只需使用'next',或者在這種情況下不太可取的是,編寫一個if-else。 –

+1

偉大的一點;僅僅因爲它是'awk'並不意味着你應該忽略最佳實踐。我根據你的建議編輯了代碼。 (我使用了一個if-else,因爲已經有了一個用next來回答的問題,對於一個剛接觸awk的人來說,條件可能會更容易理解。) – nwk

+0

謝謝,這個解決方案工作得很好! – j3pinter

2

這是join是,雖然它確實需要兩個輸入文件要在你想匹配的字段排序:如果您使用bash

sort -t\; -k2,2 datafile.txt > datafile.tmp 
sort -t\; -k1,1 lookup.txt > lookup.tmp 
join -t\; -1 2 -2 1 -o 1.1,2.2,1.3,1.4 datafile.tmp lookup.tmp | tr ';' ' ' 

,你可以將所有內容合併爲一行並跳過臨時文件:

join -t\; -1 2 -2 1 -o 1.1,2.2,1.3,1.4 <(sort -t\; -k2,2 datafile.txt) <(sort -t\; -k1,1 lookup.txt) | tr ';' ' ' 
0

您可以使用全部Bash解決方案。

while IFS=\; read _ stored; do 
    string+=($stored) 
done < lookup_file 
ref=0 
while IFS=\; read date _ data1 data2; do 
    echo $date ${string[$ref]} $data1 $data2 
    ((ref++)) 
done < data_file 

這會將查找文件中的目標字符串存儲在數組中,並在從數據文件中讀取時引用它們。

相關問題