我在AWK用我的shell脚本TR命令来掩盖的数据。 下面的示例文件会影响我的文件只有第一线,当我在AWK使用tr命令。 当我使用相同的while循环,并呼吁它里面awk命令那么它工作正常,但它采取非常长的时间来完成。 现在,我的要求,我想掩盖许多列[例如:$ 1,$ 5,$ 9]在同一个文件(file.txt的),这应该不会影响整个文件不是第一线,我想尽可能快掩盖达到这个数据。 请指教
猫file.txt的
========
abcbchs,degehek
abcbchs,degehek
abcbchs,degehek
abcbchs,degehek
abcbchs,degehek
abcbchs,degehek,lskjsjshsh
abcbchs,degehek
abcbchs,degehek,lskjsjshsh
OUTPUT
awk -F"," -v OFS="," '{ "echo \""$1"\" | tr \"a-c\" \"e-f\" | tr \"0-5\" \"6-9\"" | getline $1 }7' file.txt
effffhs,degehek
abcbchs,degehek
abcbchs,degehek
abcbchs,degehek
abcbchs,degehek
abcbchs,degehek,lskjsjshsh
abcbchs,degehek
abcbchs,degehek,lskjsjshsh
预计输出
effffhs,degehek
effffhs,degehek
effffhs,degehek
effffhs,degehek
effffhs,degehek
effffhs,degehek,lskjsjshsh
effffhs,degehek
effffhs,degehek,lskjsjshsh
你忘了close()
每次调用之后的命令。 下面就来写它的正确方法:
$ cat tst.awk
BEGIN { FS=OFS="," }
{
cmd="echo '" $1 "' | tr 'a-c' 'e-f' | tr '0-5' '6-9'"
$1 = ( (cmd | getline line) > 0 ? line : $1 )
close(cmd)
print
}
$ awk -f tst.awk file
effffhs,degehek
effffhs,degehek
effffhs,degehek
effffhs,degehek
effffhs,degehek
effffhs,degehek,lskjsjshsh
effffhs,degehek
effffhs,degehek,lskjsjshsh
您还没有保护自己的函数getline故障,因此周围,则对getline调用额外的复杂性,看到http://awk.info/?tip/getline 。
鉴于您的意见,这显示了如何同时修改多个字段(1,3,5在这种情况下):
$ cat tst.awk
BEGIN { FS=OFS="," }
{
cmd = "echo '" $0 "' | tr 'a-c' 'e-f' | tr '0-5' '6-9'"
new = ( (cmd | getline line) > 0 ? line : $1 )
close(cmd)
split(new,tmp)
for (i in tmp) {
if (i ~ /^(1|3|5)$/) {
$i = tmp[i]
}
}
print
}
$ cat file
abc,abc,abc,abc,abc
abc,abc,abc,abc,abc,abc,abc
abc,abc,abc,abc,abc,abc
abc,abc,abc,abc
$ awk -f tst.awk file
eff,abc,eff,abc,eff
eff,abc,eff,abc,eff,abc,abc
eff,abc,eff,abc,eff,abc
eff,abc,eff,abc
为了处理输入数据的报价:
$ cat tst.awk
BEGIN { FS=OFS="," }
{
gsub(/'/,SUBSEP)
cmd = "echo '" $0 "' | tr 'a-c' 'e-f' | tr '0-5' '6-9'"
new = ( (cmd | getline line) > 0 ? line : $1 )
close(cmd)
split(new,tmp)
for (i in tmp) {
if (i ~ /^(1|3|5)$/) {
$i = tmp[i]
}
}
gsub(SUBSEP,"'")
print
}
$ cat file
a'c,abc,a"c,abc,abc
abc,a'c,abc,a"c,abc,abc,abc
abc,abc,abc,abc,abc,abc
abc,abc,abc,abc
$ awk -f tst.awk file
e'f,abc,e"f,abc,eff
eff,a'c,eff,a"c,eff,abc,abc
eff,abc,eff,abc,eff,abc
eff,abc,eff,abc
如果你没有有保证不会出现在你输入的任何特殊字符的控制,您可以通过上述使用在结束中描述的技术创建一个不存在的字符串,而不是SUBSEP的使用https://stackoverflow.com/一个/一百七十四万五千零一分之二千九百二十三万七千七百四十五
你找到的代码运行在每个输入行的外壳命令管道。 就像你发现,这是一个非常低效的方式做你的要求。 AWK是不是真正完成这个任务,在所有的理想选择。 也许尝试的Perl。
perl -F, -lane '$F[$_] =~ tr/a-c/e-f/ =~ tr/0-5/6-9/ for (0, 4, 8); print join(",", @F)' file
该-F,
一个选项是类似使用awk,但Perl不会自动分割输入线。 随着-a
它,分裂成一个名为数组@F
,并与-n
它遍历所有的输入行。 该-l
是为了方便从各个输入线和添加一回当你打印删除换行符。
注意列是如何从零开始编号,不是一个,像awk中; 所以指数在for
环路接第一,第五和第九的元素@F
。