BASH 在键上逐行减去文件

发布于 2024-11-17 15:47:31 字数 1171 浏览 1 评论 0原文

我只想从一个 CSV 文件中减去另一个文件,但如果行相同则不会。我不想比较这些行,而是想看看这些行是否在一个字段中匹配。

例如,第一个文件

EMAIL;NAME;SALUTATION;ID
[email protected];Foo;Mr;1
[email protected];Bar;Ms;2

和第二个文件的

EMAIL;NAME
[email protected];Foo

结果文件应该是

EMAIL;NAME;SALUTATION;ID
[email protected];Bar;Ms;2

我想你知道我的意思;)

这在bash中怎么可能?对我来说,在 Java 中执行此操作很容易,但我真的很喜欢学习如何在 bash 中执行此操作。我也可以通过使用 sort 比较行来进行减法,

#! / bin / bash    
echo "Substracting Files..."

sort "/tmp/list1.csv" "/tmp/list2.csv" "/tmp/list2.csv" | uniq -u >> /tmp/subList.csv

echo "Files successfully substracted."

但这些行不是同一个元组。所以我必须将线路与按键进行比较。

有什么建议吗?非常感谢..尼尔斯

I just wanna to substract one CSV-File from another one, but not if the lines are the same. Instead of comparing the lines I'd like to look if the lines matching in one field.

e.g. the first file

EMAIL;NAME;SALUTATION;ID
[email protected];Foo;Mr;1
[email protected];Bar;Ms;2

and the second file

EMAIL;NAME
[email protected];Foo

the resultfile should be

EMAIL;NAME;SALUTATION;ID
[email protected];Bar;Ms;2

I think u know what I mean ;)

How is that possible in bash? It's easy for me doing this in Java, but I realy like to learn how to do that in bash. Also I can substract by comparing the lines using sort

#! / bin / bash    
echo "Substracting Files..."

sort "/tmp/list1.csv" "/tmp/list2.csv" "/tmp/list2.csv" | uniq -u >> /tmp/subList.csv

echo "Files successfully substracted."

But the lines arn't the same tuple. So I have to compare line with keys.

Any suggestions? Thanks a lot.. Nils

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最单纯的乌龟 2024-11-24 15:47:31

我想到的一种可能的解决方案是这个(使用 bash):

grep -v -f <(cut -d ";" -f1 /tmp/list2.csv) /tmp/list1.csv

这意味着:
<代码>剪切-d“;” -f1 /tmp/list2.csv:提取第二个文件的第一列。
grep -f some_file:使用文件作为模式源。
<(some_command):这是一个进程替换。它执行命令并将输出提供给命名管道,然后可以将其用作 grep -f 的文件输入。
grep -v:仅打印与模式不匹配的行。

One possible solution coming to my mind is this one (working with bash):

grep -v -f <(cut -d ";" -f1 /tmp/list2.csv) /tmp/list1.csv

That means:
cut -d ";" -f1 /tmp/list2.csv: Extract the first column of the second file.
grep -f some_file: Use a file as pattern source.
<(some_command): This is a process substitution. It executes the command and feeds the output to a named pipe which then can be used as file input to grep -f.
grep -v: Print only the lines not matching the pattern(s).

洒一地阳光 2024-11-24 15:47:31

更新:通过joinawk解决问题。

join --header -1 1 -2 1 -t";" --nocheck-order -v 1 1.csv 2.csv | | awk 'NR==1 {print gensub(";[^;]\\+$","","g");next} 1'     

这些是相反的答案:

$ join -1 1 -2 1 -t";" --nocheck-order -o 1.1,1.2,1.3,1.4 1.csv 2.csv 
EMAIL;NAME;SALUTATION;ID
[email protected];Foo;Mr;1

加入来救援。

或者跳过不带 -o 打印 NAME 字段:(

$ join -1 1 -2 1 -t";" --nocheck-order 1.csv 2.csv | awk 'BEGIN {FS=";" ; OFS=";"} {$NF=""; print }'

但它仍然在最后一个字段之后打印一个加号 ;

˛。HTH

Update: the solution to the question, via join and awk.

join --header -1 1 -2 1 -t";" --nocheck-order -v 1 1.csv 2.csv | | awk 'NR==1 {print gensub(";[^;]\\+$","","g");next} 1'     

These were the inverse answers:

$ join -1 1 -2 1 -t";" --nocheck-order -o 1.1,1.2,1.3,1.4 1.csv 2.csv 
EMAIL;NAME;SALUTATION;ID
[email protected];Foo;Mr;1

join to the rescue.

Or the skipping of printing the NAME field without -o:

$ join -1 1 -2 1 -t";" --nocheck-order 1.csv 2.csv | awk 'BEGIN {FS=";" ; OFS=";"} {$NF=""; print }'

(But it still prints a plus ;˛after the last field.

HTH

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文