2013-03-16 50 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