【发布时间】:2013-03-16 18:47:50
【问题描述】:
我有管道分隔的文本文件,需要特定字段或一组字段的 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。 您的建议将不胜感激
【问题讨论】:
-
您是否尝试打印
sed行以查看参数替换是否正确完成?有人认为echo "$line \| sed -e \"s/$MYFIELD/${MYHASH}/g" -
@fedorqui 替换似乎大部分时间都可以正常工作。它崩溃的地方是当要散列的字段包含一组与我不想散列的另一个字段匹配的字符时。例如,donthashit|foo1|bar1|foo2|bar2|hashit 将按照应有的方式散列字段 6,但 sed 在第一个字段和最后一个字段中都看到 hashit 并替换两者。这是一个问题,因为我只希望它操纵字段 6。
-
如果你指定
/g,每次找到它都会改变它。你有什么模式可以区分它们吗? -
我不确定我知道,但我相信在大多数(也许是所有?)情况下,冲突将与第一个字段发生冲突。由于第一个字段之前没有管道,我可以确保我只替换以管道开头的字符串。那是你开车去的地方吗?
-
经过一些测试,我想我通过
awk得到了它。请看下面的答案。这样我们就可以只替换我们想要的字段(在这种情况下是第 6 个)。