使用 awk 从文件中提取数据时出现问题

使用 awk 从文件中提取数据时出现问题

我有一个大型数据文件,想根据第 1 列的值将其拆分为较小的文件。例如,第 1 列有 1 到 10 的数字 10 次,形成 100 行,并且我希望所有带有数字“1”或“2”或“3”等的行都在它们自己的文件中(最好不排序)。另外,我不想运行该命令 10 次,因此希望它处于循环中。

我的文件如下所示:

  • text.txt

    在此处输入图片描述

  • ID.txt

    1
    2
    3
    4
    

我尝试过的命令:

cat ID.txt | while read line; do awk '$1 == ${line}' test.txt >$line.txt;done

总而言之,我希望它从 ID.txt 文件中读取值,例如“1”,然后提取第一行带有“1”的所有行并将其放入名为 1.txt 的文件中,然后迭代到 2、3、4 等。

但不知何故,我认为 '$1 == ${line}' 部分不起作用

答案1

您正在寻找以下-v选项awk

   -v var=val
   --assign var=val
          Assign the value val to the variable var,  before  execution  of
          the  program  begins.  Such variable values are available to the
          BEGIN rule of an AWK program.

像这样:

cat ID.txt | 
    while read line; do awk -vline="$line" '$1 == l' test.txt >"$line".txt;done

更好的表达方式是(避免无用地使用 cat):

while read line; do 
    awk -vline="$line" '$1 == l' test.txt >"$line".txt;
done < ID.txt

但是,这非常慢且效率低下。您正在对 的每一行运行awk命令。为什么不直接读取它本身并打印匹配的行呢:test.txtID.txtID.txtawk

awk 'NR==FNR{a[$1]++; next} ($1 in a){print >> $1".txt"}' ID.txt test.txt 

上述代码将 的第一个字段保存ID.txt在数组 中aNRFNR是特殊awk变量,表示“输入流的当前行”和“当前文件的当前行”。 只有在读取第一个文件时,这两个变量才会相等。 因此,NR==FNR{a[$1]++; next}只会在第一个文件的行上运行。 第二部分将不会被执行,因为 指示next跳到awk下一行。

第二部分,检查当前行的第一个字段(记住,这只在第二个文件上运行)是否存在于数组中a(这意味着它在ID.txt),如果存在,则将该行打印到名为“field1.txt”的文件中

相关内容