我用awk没什么问题,因为它会让我白发苍苍..

我有两个内容不同的文件,但第一列的值是相同的.

文件在脚本期间生成为CSV文件(以分号分隔)和如下所示的锁定:

main_file.csv
---
151597-21;151597;21;3;15;;"Vente OK";excluded
151598-21;151598;21;3;15;;"Vente OK";excluded
151599-0;151599;0;0;10;;;programmed
151600-0;151600;0;0;10;;;programmed
151601-0;151601;0;0;10;;;programmed
151602-0;151602;0;0;10;;;programmed
151603-0;151603;0;0;10;;;programmed
151604-0;151604;0;0;10;;;programmed
151605-0;151605;0;0;10;;;programmed
151606-0;151606;0;0;10;;;programmed
151607-0;151607;0;0;10;;;programmed
...
151622-0;151622;0;0;10;;;programmed
151623-0;151623;0;0;10;;;programmed
151624-0;151624;0;0;10;;;programmed
151625-0;151625;0;0;10;;;programmed
...


filter_file.csv
---
151622-0;151622;0

我想比较这两个文件,并创建第三个文件,该文件包含"main_file.csv"中的行,该行与"Filter_file.csv"中的行匹配,使用第一个列值作为比较.

如示例所示,我应该得到一个包含一行的"ResultFile.csv",但不幸的是,我得到的是一个空文件.

专家输出应为:

151622-0;151622;0;0;10;;;programmed

这是我试过的命令:

awk 'BEGIN {FS=OFS=";"} NR==FNR{a[$1]=1; next} a[$1]{print}' filter_file.csv main_file.csv > result_file.csv

如果我理解正确的话,它应该是这样解释的:

awk '                           # starting awk program
BEGIN {FS=OFS=";"}              # define column separator as commat for both files (main & filter)
NR==FNR{a[$1]=1; next}          # during read of the first file (filter_file.csv), create an array 'a' with first column value as index
a[$1]{print}                    # during read of the second file (main_file.csv), if first column value exist as an index of the array 'a', print the whole line in the 'result_file.csv'
' 
filter_file.csv main_file.csv   # files to be compared
> result_file.csv               # direct the output to the third file

但我恐怕错过了一些东西:/

编辑:更新以添加一些上下文:

该命令是从如下所示的php脚本执行的:

$awk_cmd = 'awk \'BEGIN {FS=OFS=";"} NR==FNR {a[$1]=1; next} $1 in a {print}\' ' . $filter_file . ' ' . $ref_file . ' > ' . $match_file;
exec($awk_cmd);

其中,$FILTER_FILE、$REF_FILE和$MATCH_FILE是文件的完整路径.

EDIT2 :
I tested the grep command and get the following output:

0000000   1   5   1   6   2   2   -   0   ;   1   5   1   6   2   2   ;
0000020   0   ;   0   ;   1   0   ;   ;   ;   p   r   o   g   r   a   m
0000040   m   e   d  \r  \n
0000045

推荐答案

首先,感谢大家的建议!

我自己回答说,因为没有一个答案完全解决了这个问题,尽管完整的解决方案是@Hard编码建议和@Renaud Pacalet重写awk命令的混合.

我没有在我的问题中指明的事情(因为当时我认为这不会有任何影响)是,我在Windows 10的本地环境中测试了代码,这是问题的一部分,正如@Hard所建议的那样……

因此,在执行awk命令之前,我在代码中添加了一个步骤来转换要比较的文件:

dos2unix filter_file.csv main_file.csv

我还修改了为AWF指定列分隔符的方式,就像@Renaud Pacalet建议的那样(相反,这给了我以下命令:

awk -F';' 'NR==FNR {a[$1]=1; next} $1 in a {print}' filter_file.csv main_file.csv > result_file.csv

这两个变化结合在一起给了我正确的结果.

在我php脚本中,它给出了如下内容:

$convert = 'dos2unix  ' . $filter_file . ' ' . $ref_file;
exec($convert);

$awk_cmd = 'awk -F\';\' \'NR==FNR {a[$1]=1; next} $1 in a {print}\' ' . $filter_file . ' ' . $ref_file . ' > ' . $match_file;
exec($awk_cmd);

其中使用变量调用文件,因为它包含指向它的完整路径.

一旦应用了这些命令,一切都在我的本地服务器上运行,但在测试服务器(Ubuntu)上推送一次后,我们仍然收到错误消息. 原来,测试服务器上没有安装dos2unix... 一旦安装好,一切都会按预期运行.

尽管如此,我还是不明白为什么当过滤器文件只包含一行时,我才会遇到这个问题.当过滤器文件包含几行时,我从来没有阻止这个问题,奇怪的是...

Linux相关问答推荐

Bash脚本用于在远程工作后关闭用户会话

使用Bash从文件名中删除日期名称

如何正确Forking 并完成进程以避免 EAGAIN 错误

Docker 不保留 chown 用户设置

如何在具有多种可能性的linux shell中获取最大值和最小值?

X86 程序集 - struct 点 - 存储/返回不正确?

如果列小于 X,linux 合并行

Qt会泄漏内存吗?

如何在 gcc 搜索路径上防止多个版本的 Boost?

将 Visual Studio C++ 项目迁移到 Linux 和 CMake

你如何在 CentOS9 上使用 C++ fmt?

使用 awk 将 csv 拆分为带有标题的多个文件

如何像 Nautilus 那样从命令行挂载?

exec 系统调用(如 exec 和 execve)系列的功能有什么区别?

有没有办法在整个项目代码中的某个日期之后找出更改的文件?

如何以另一个用户的身份使用 sudo 在 bash 子shell 中执行一系列命令?

*nix 系统上是否有与 COM 等效的功能?如果不是,那么 *nix 的可重用性方法是什么?

可以通过 SSH 连接的所有用户的列表

在 bash 中将输出作为 cp 的参数传递

JAVA_HOME 和 PATH 已设置,但 java -version 仍显示旧版本