2

我有管道分隔的文本文件,需要特定字段或一组字段的 MD5 哈希。因为我在 AIX 上并且必须使用 csum 函数,所以我认为我不能简单地将文件和散列函数传递给 awk 以一举完成。

所以我正在编写一个脚本,它读取每一行,将要散列的字段传递给 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。您的建议将不胜感激

4

1 回答 1

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"让awk-v n="$new"处理变量并$old分别$new命名它们。 on
  • {OFS=FS}- 定义字段之间的分隔符。也可能是OFS="|",但这种方式我们指示awk使用我们定义的相同-F="|"。保留字段分隔符以防它发生变化更加灵活。
  • sub(o, n, $6)将变量(即 )上的文本替换为变量(o$MYFIELD)上的文本,但在字段 6 上。 v$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

希望能帮助到你。

编辑
找到了一种轻松将变量传递给 awk 的方法:-v o=${variable_name}

这样,解决方案可以是:

echo $line | awk -F"|" -v o=${MYFIELD} -v n=${MYHASH} '{OFS=FS} sub(o, n, $6) {print}' >> $2
于 2013-03-16T20:11:09.793 回答