另一种解决方案

 另一种解决方案

我有一个大文件:(file1.csv)

id,code,N
10214411,008.8,1
10214411,038.9,1
10214411,04.81,1
10214411,07.22,1

想要根据带有 ID 列表的第二列选择并生成新文件,例如:

第二个文件有第二列的大量 ID 列表,例如:(file2.csv):

0.008.8
07.22

结果:(文件3.csv)

id,code,N
10214411,008.8,1
10214411,07.22,1

答案1

假设0.008.8您问题中的 in file2.csv 是一个拼写错误,而应该是008.8这样,看起来这就是您想要的:

awk -F, 'NR==FNR{a[$1]; next} FNR==1 || $2 in a' file2.csv file1.csv > file3.csv

例如:

$ awk -F, 'NR==FNR{a[$1]; next} FNR==1 || $2 in a' file2.csv file1.csv
id,code,N
10214411,008.8,1
10214411,07.22,1

答案2

像这样,使用bashshell,paste并且awk

输入文件

$ cat file2.csv
008.8
07.22

代码

通过 shell 变量中的一些小技巧来制作正则表达式:

re="^($(paste -sd '|' file2.csv))$" 

...现在,$re变量包含正则表达式^(008.8|07.22)$

然后,将 re 作为变量传递给 awk : (${re//./\\.}是 bash 参数扩展为反斜杠点 => ^(008\.8|07\.22)$)

awk -F, -v re="${re//./\\.}" 'NR==1 || $2 ~ re' file1.csv | tee file3.csv 

 输出

$ cat file3.csv
id,code,N
10214411,008.8,1
10214411,07.22,1

 另一种解决方案

(未测试)

{ 
    echo 'id,code,N'
    while IFS=, read -r _ id __; do
        awk -F, -v id=$id '$2==id' file1.csv
    done < file2.csv 
} | tee -a file3.csv

答案3

head并将grep共同完成这项工作:grep -F因此 grep 将 file2 中的行视为固定字符串而不是正则表达式。

{
  head -n 1 file1.csv
  grep -F -f file2.csv file1.csv
}
id,code,N
10214411,008.8,1
10214411,07.22,1

我在这里使用大括号,这样可以更轻松地同时重定向两个命令的输出:

{ cmd1; cmd2; ...; } > output.txt

相关内容