虽然使用awk显示致命:无法打开管道(太多打开文件)错误

时间:2017-09-14 17:29:15

标签: awk

我试图使用命令'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

3 个答案:

答案 0 :(得分:1)

首先,您不能在-Fv之间留出空格。

我打算建议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