2013-03-16 33 views
2

我有管道分隔的文本文件,需要特定字段或字段集的MD5散列。因爲我在AIX上並且必須使用csum函數,所以我不認爲我可以簡單地通過文件和哈希函數awk來一舉完成。結合awk和csum來散列字段

因此,我正在編寫一個腳本,通過讀取每一行,將需要哈希的字段傳遞給csum,然後通過gsub將結果作爲替換放回。 99%的時間似乎工作正常,但有時會發生什麼事情,因爲gsub取代了它不應該的東西。

#!/bin/ksh 
rm $2 #Get rid of output file 
while read line; do #loop through each line 
MYFIELD=$(echo "$line" | cut -d "|" -f 6); #push the 6th field into a var 
MYHASH=$(echo $MYFIELD | csum -h MD5 -); #csum will hash a string only on the stdin 
echo $line | sed -e "s/$MYFIELD/${MYHASH}/g" >> $2 #gsub replaces, but not always what we want 
done < $1 #read in the input file 

我想我可以使用awk來更新字段。但是,我無法一次完成這一行。理想情況下,我希望有一個腳本允許我傳遞兩個必需的參數(infile和outfile),然後傳遞任意數量的將被散列和替換的字段位置。一拉

foo infile.txt outfile.txt 2 6 12 

這將在infile.txt閱讀,哈希場2,6,12,寫出來給outfile.txt。 你的建議將不勝感激

+0

您是否嘗試過打印'sed'線,看是否參數替換是否正確完成?有些東西像'echo'$ line \ | sed -e \「s/$ MYFIELD/$ {MYHASH}/g」' – fedorqui 2013-03-16 19:22:00

+0

@fedorqui替換似乎在大多數情況下都能正常工作。被散列包含一組匹配另一個我不想散列的字段的字符,例如,donthashit | foo1 | bar1 | foo2 | bar2 | hashit將散列字段6,但sed在第一個字段和這是一個問題,因爲我只希望它操作字段6. – 2013-03-16 19:34:54

+0

如果你指出'/ g'它會在每次找到它時改變它。你有任何模式來區分它們嗎? – fedorqui 2013-03-16 19:44:27

回答

3

怎麼樣做awk

而不是

echo $line | sed -e "s/$MYFIELD/${MYHASH}/g" >> $2 #gsub replaces, but not always what we want 

您可以使用

old=$MYFIELD; new=$MYHASH; echo $line | awk -F"|" -v o="$old" -v n="$new" '{OFS=FS} sub(o, n, $6) {print}' >> $2 

基本上我們做的是:

  • old=$MYFIELD; new=$MYHASH我們指定的參數是發送awk
  • echo $line我們輸出該行以便awk可以獲取它。

在AWK,

  • -F"|"限定|作爲字段分隔符。
  • -v o="$old"-v n="$new"與變數,awk的工作$old$new它們分別命名爲on
  • {OFS=FS} - 定義字段之間的分隔符。它也可以是OFS="|",但是這種方式我們指示awk使用我們在-F="|"上定義的相同。如果字段分隔符發生變化,保留字段分隔符更爲靈活。
  • sub(o, n, $6)替換可變o與可變v文本上字段6中的文本(即,$MYFIELD)(即,$MYHASH),但只是
  • print與取代文字的整條生產線

這個例子的工作對我來說,你給上評論:

old="hashit"; new="WE_DID"; echo "donthashit|foo1|bar1|foo2|bar2|hashit" | awk -F"|" -v o="$old" -v n="$new" '{OFS=FS} sub(o,n,$6) {print}' 
donthashit|foo1|bar1|foo2|bar2|WE_DID 

希望它能幫助。

編輯
found a way傳遞變量輕鬆awk的:-v o=${variable_name}

這樣,該解決方案可以是:

echo $line | awk -F"|" -v o=${MYFIELD} -v n=${MYHASH} '{OFS=FS} sub(o, n, $6) {print}' >> $2 
+0

不錯,看起來不錯。你的解釋特別有用。但是分隔符不保留;空格似乎已被替換。我會鼓搗一下 – 2013-03-16 20:46:37

+0

你是對的,@ Amw5G,我以前沒有看到它。我只是編輯了我的答案以包含答案:我們需要使用「{OFS = FS}」來定義分隔符。現在它應該工作。 – fedorqui 2013-03-16 20:59:20

+1

優秀@fedorqui,似乎這樣做。乾杯! – 2013-03-16 21:35:56