在awk命令中使用-v时脚本返回'/ usr / bin / awk:参数列表太长'

时间:2017-09-04 02:43:46

标签: bash csv awk

以下是我的脚本中使用 awk 的部分。

ids=`cut -d ',' -f1 $file | sed ':a;N;$!ba;s/\n/,/g'`
awk -vdata="$ids" -F',' 'NR > 1 {if(index(data,$2)>0){print $0",true"}else{print $0",false"}}' $input_file >> $output_file

这很有效,但当我尝试将数据传输到两个或更多这样的文件时。

ids=`cut -d ',' -f1 $file1 $file2 $file3 | sed ':a;N;$!ba;s/\n/,/g'`

它返回了此错误。

/usr/bin/awk: Argument list too long

正如我研究的那样,它不是由文件数量引起的,而是由 ids 提取的数量引起的。

有人知道如何解决这个问题吗?感谢。

3 个答案:

答案 0 :(得分:1)

您可以使用环境变量将数据传递给awk。在awk中,可以通过数组ENVIRON访问环境变量。

所以尝试这样的事情:

export ids=`cut -d ',' -f1 $file | sed ':a;N;$!ba;s/\n/,/g'`
awk -F',' 'NR > 1 {if(index(ENVIRON["ids"],$2)>0){print $0",true"}else{print $0",false"}}' $input_file >> $output_file

答案 1 :(得分:0)

更改生成ids的方式,以便它们每行出一个,就像这样,我将其用作生成ids 2,3和9的非常简单的方式:

echo 2; echo 3; echo 9
2
3
9

现在将其作为第一个文件传递给awk,将$input_file作为第二个文件传递给awk

awk '...' <(echo 2; echo 3; echo 9) "$input_file"

bash中,您可以使用<(some commands)生成包含流程输出的伪文件,这就是我正在使用的内容。

现在,在awk中,从第一个文件中选择ids,如下所示:

awk 'FNR==NR{ids[$1]++;next}'  <(echo 2; echo 3; echo 9)

将设置ids[2]=1ids[3]=1ids[9]=1

然后传递两个文件并添加原始处理:

awk 'FNR==NR{ids[$1]++;next} {if($2 in ids) print $0",true"; else print $0",false"}'  <(echo 2; echo 3; echo 9) "$input_file"

因此,对于我的最终答案,您的整个代码将如下所示:

awk 'FNR==NR{ids[$1]++;next} {if($2 in ids) print $0",true"; else print $0",false"}'  <(cut ... file1 file2 file3 | sed ...) "$input_file"

正如@ hek2mgl在评论中提到的那样,您可以直接将包含ids的文件传递给awk 并让awk找到ids本身,而不是使用cutsed。如果有很多,您可以将它们全部作为第一个文件awk来到

awk '...' <(cat file1 file2 file3) "$input_file"

答案 2 :(得分:0)

您的脚本中存在2个问题:

awk -vdata="$ids" -F',' 'NR > 1 {if(index(data,$2)>0){print $0",true"}else{print $0",false"}}' $input_file >> $output_file

可能导致该错误:

  1. -vdata=.. - 这是特定的gawk,在其他问题中,您需要在-vdata=之间留出空格。所以如果你没有运行gawk然后idk你的awk会对那个语句做什么,但它可能会把它当作多个args。
  2. $input_file - 你必须引用shell变量,除非你有一个特定的目的,让它们不加引号。如果$input_file包含globbing字符或空格,那么不加引号将使它们扩展为可能的多个文件/ args。
  3. 所以试试这个:

    awk -v data="$ids" -F',' 'NR > 1 {if(index(data,$2)>0){print $0",true"}else{print $0",false"}}' "$input_file" >> "$output_file"
    

    看看你是否还有问题。你的脚本当然有其他无关的问题,其中一些已经被指出了,你可以发布一个后续问题,如果你需要帮助那些,但只是FYI,awk脚本可以更简洁地写成:

    awk -v data="$ids" 'BEGIN{FS=OFS=","} NR > 1{print $0, (index(data,$2) ? "true" : "false")}'