我试图使用命令'tr'和'awk'来屏蔽文件,但是因为错误致命而失败:无法打开管道(太多打开的管道)错误。 FILE有大约1000000条记录,数量巨大。 以下是我正在尝试的代码: -
awk - F "|" - v OFS="|" '{ "echo \""$1"\" | tr \" 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\" \" QWERTYUIOPASDFGHJKLZXCVBNM9876543210mnbvcxzlkjhgfdsapoiuytrewq\"" | get line $1}1' FILE.CSV > test.CSV
显示错误: -
awk: (FILENAME=- FNR=1019) fatal: cannot open pipe `echo ""TTP_123"" | tr "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" "QWERTYUIOPASDFGHJKLZXCVBNM9876543210mnbvcxzlkjhgfdsapoiuytrewq"' (Too many open pipes)
请告诉我这里我做错了什么 另外注意任意数量的列可用于屏蔽,并且可以在此示例中的任何位置我已经采用1和2列位置但它可以是3和10或5,7,25列 谢谢 AJ
答案 0 :(得分:1)
首先,您不能在-
和F
或v
之间留出空格。
我打算建议sed
,但由于您只想翻译第一列,这并不容易。
不幸的是,awk
没有内置的tr
功能,因此您必须像使用shell一样使用shell并关闭管道:
awk -F "|" -v OFS="|" '{
command="echo \"\\"$1"\\\" | tr \" 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\" \" QWERTYUIOPASDFGHJKLZXCVBNM9876543210mnbvcxzlkjhgfdsapoiuytrewq\""
command | getline $1
close(command)
}1' FILE.CSV > test.CSV
但是,我建议使用perl
,它可以进行字段拆分和字符转换:
perl -F'\|' -lane '$F[0] =~ tr/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/QWERTYUIOPASDFGHJKLZXCVBNM9876543210mnbvcxzlkjhgfdsapoiuytrewq/; print join("|", @F)' FILE.CSV > test.CSV
或者,对于较短的命令行,只需将程序放入文件中,将e
放入-lane
并使用文件名而不是'...'
命令。
答案 1 :(得分:0)
你可以在awk
中进行映射,而不是为每一行进行系统调用,或者只是简单地
paste -d'|' <(cut -d'|' -f1 file | tr '0-9' 'a-z') <(cut -d'|' -f2- file)
用你的tr
参数替换。
答案 2 :(得分:0)
这不能解答您的问题,但您可以将tr
实现为一个awk函数,可以节省必须产生大量外部进程
$ cat tr.awk
function tr(str, from, to, s,i,c,idx) {
s = ""
for (i=1; i<=length($str); i++) {
c = substr(str, i, 1)
idx = index(from, c)
s = s (idx == 0 ? c : substr(to, idx, 1))
}
return s
}
{
print $1, tr($1,
" 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
" QWERTYUIOPASDFGHJKLZXCVBNM9876543210mnbvcxzlkjhgfdsapoiuytrewq")
}
示例:
$ printf "%s\n" hello wor-ld | awk -f tr.awk
hello KGCCN
wor-ld 3N8-CF