Unix 结合awk和csum对字段进行散列
我有管道分隔的文本文件,它需要一个特定字段或一组字段的MD5散列。因为我在AIX上,必须使用csum函数,所以我不认为我可以简单地将文件和哈希函数传递给awk来一次性完成 因此,我正在编写一个脚本,它读取每一行,将要散列的字段传递给csum,然后通过gsub将结果作为替换返回。99%的情况下,它似乎工作正常,但有时会发生冲突,因为gsub替换了不应该使用的东西Unix 结合awk和csum对字段进行散列,unix,awk,md5,delimiter,Unix,Awk,Md5,Delimiter,我有管道分隔的文本文件,它需要一个特定字段或一组字段的MD5散列。因为我在AIX上,必须使用csum函数,所以我不认为我可以简单地将文件和哈希函数传递给awk来一次性完成 因此,我正在编写一个脚本,它读取每一行,将要散列的字段传递给csum,然后通过gsub将结果作为替换返回。99%的情况下,它似乎工作正常,但有时会发生冲突,因为gsub替换了不应该使用的东西 #!/bin/ksh rm $2 #Get rid of output file while read line; do #loop t
#!/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
它将读取infle.txt、散列字段2、6和12,并写入outfile.txt。
非常感谢您的建议使用
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
我们输出该行以便awk可以获取它李>echo$line
将-F“|”
定义为字段分隔符李>|
和-vo=“$old”
让awk分别使用变量-vn=“$new”
和$old
命名它们李>$new
-定义字段之间的分隔符。它也可以是{OFS=FS}
,但这样我们指示OFS=“|”
使用我们在awk
上定义的相同代码。在字段分隔符发生变化时,保留字段分隔符更为灵活李>-F=“|”
将变量sub(o,n,$6)
(即,o
)上的文本替换为变量$MYFIELD
(即,v
)上的文本,但仅在字段6上李>$MYHASH
用替换文本打印整行打印
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:
-vo=${variable\u name}
这样,解决方案可以是:
echo $line | awk -F"|" -v o=${MYFIELD} -v n=${MYHASH} '{OFS=FS} sub(o, n, $6) {print}' >> $2
您是否尝试打印
sed
行以查看参数替换是否正确完成?有些想法像echo“$line\| sed-e\”s/$MYFIELD/${MYHASH}/g“
@fedorqui这种替代品在大多数情况下似乎都很有效。当要散列的字段包含一组字符,这些字符与我不希望散列的另一个字段相匹配时,就会出现故障。例如,donthashit | foo1 | bar1 | foo2 | bar2 | hashit将按其应该的方式对字段6进行散列,但sed在第一个字段和最后一个字段中都看到了hashit,并将其替换。这是一个问题,因为我只希望它处理字段6。如果您指示/g
,它将在每次找到它时更改它。你有什么模式来区分它们吗?我不确定我知道,除了我相信在大多数(也许所有?)情况下,冲突都会发生在第一个领域。因为第一个字段前面没有管道,所以我可以确保只替换以管道开头的字符串。这就是你要开车去的地方吗?经过一些测试,我想我用awk
得到了它。请看下面的答案。这样我们就可以替换我们想要的字段(本例中为第6个)。很好,看起来很不错。你的解释特别有用。但是,分隔符不被保留;空格似乎已被替换。我会稍加修改的。你说得对,@Amw5G,我以前没见过。我刚刚编辑了我的答案以包含它的答案:我们需要使用{OFS=FS}
来定义分隔符。现在它应该可以工作了。好极了@fedorqui,似乎可以。干杯
echo $line | awk -F"|" -v o=${MYFIELD} -v n=${MYHASH} '{OFS=FS} sub(o, n, $6) {print}' >> $2