这是一个美丽的东西(我认为):

这是一个美丽的东西(我认为):

文件1.csv

A,,C,D
A,,C,D
A,,C,D
A,,C,D

文件2.csv

A,B
A,B
A,B
A,B

所需输出.csv

A,B,C,D
A,B,C,D
A,B,C,D
A,B,C,D

我尝试使用“join”和“paste”,但无济于事。有没有 bash 命令可以做到这一点?两个.csv文件中的“A”列相同。

答案1

仅使用awk命令:

awk -F, '{getline f1 <"file2" ;print f1,$3,$4}' OFS=, file1

从文件1中取出一行存入局部变量中f1,然后打印该行f1,最后打印文件1中以逗号分隔的第三( $3)和第四( )字段,并将OFS(输出字段分隔符[默认为空格])更改为逗号()。$3,,


简短的命令如下:

paste -d, file2 <(cut -d, -f3- file1)
A B C D  
 A B C D  
 A B C D  
 A B C D  

粘贴文件 2,然后-f3-从文件 1 剪切并粘贴第三列到下一个()。


awkpaste(选项 A)

以下命令还将文件 1 的最后两列(C,D)复制到文件 2 中每行的末尾:

paste -d',' file2  <(awk -F',' '{print $(NF-1)","$NF}' file1)

以上命令粘贴然后,file2 的内容打印一个逗号分隔符(-d','),然后粘贴 file1 中的最后两个字段(NF是最后一个字段的索引,$NF是其索引所在的字符串NF。所以$(NF-1)是最后一个字段之前的第二个字段),当这些索引用逗号观察者(-F',')重新定义或拆分时。

awkpaste(选项 B)

该命令也与上面的相同($3指向$4file1 中每行的第三和第四个字段):

paste -d',' file2  <(awk -F',' '{print $3","$4}' file1)

或者使用cut命令的另一种解决方案:

paste -d, <(cut -d, -f1 file1) <(cut -d, -f2 file2) <(cut -d, -f3- file1)

上述命令中的命令首先从 file1() 中剪切第一个字段(以逗号分隔符( )-f1作为索引) ,然后剪切并粘贴 file2() 的第二个字段,最后再次从 file1( ) 中剪切并粘贴第三列()到 nexts( )。-d.cut -d, -f1 file1cut -d, -f2 file2-f3-cut -d, -f3- file1

此命令也返回相同的结果:

paste -d, <(awk -F',' '{print $1}' file1) <(awk -F',' '{print $2}' file2) <(awk -F',' '{print $3","$4}' file1)

从 file1() 粘贴第二个字段,awk -F',' '{print $1}' file1然后打印逗号(-d,),然后从 file2() 粘贴第二列awk -F',' '{print $2}' file2,最后再次粘贴 file1( awk -F',' '{print $3","$4}' file1) 的第二列和最后一列。

答案2

这是一个美丽的东西(我认为):

join -t, <(csvcut -c 1,3,4 file1.csv) <(csvcut -c 1,2 file2.csv)

分解如下步骤:

步骤1.安装csvkit:

sudo pip install csvkit
sudo apt-get install python-dev python-pip python-setuptools build-essential

步骤 2. 使用 join 命令并以逗号作为分隔符

join -t,

步骤 3. 输入您想要的实际列。请注意,您如何两次输入第一列,因为这是实际执行连接的列(的默认行为join)。

join -t, <(csvcut --columns 1,3,4 file1.csv) <(csvcut --columns 1,2 file2.csv)

或者简写为:

join -t, <(csvcut -c 1,3,4 file1.csv) <(csvcut -c 1,2 file2.csv)

如果需要,您可以将标准输出重定向到文件(desiredOutput)。

优点

与所提出的其他方法相比,该方法有几个优点。

首先:它执行真正的连接。这意味着它也可以用于更复杂的数据。例如,对另一个字段进行连接非常容易。它不是简单地查看字段的位置,而是真正考虑列。它实际上使用数据格式 (csv),而不是将其视为文本。

其次,它使用非常强大的 csv 工具包,该工具包还允许您 a) 使用一个命令显示统计数据 ( csvstats),b) 检查数据是否干净 ( csvclean),还可以将其转换为 json、sql,甚至将其加载到 python 中!该工具包在数据科学中被广泛用于数据准备。

答案3

这是另一个很棒的建议。我认为到目前为止,这是所有建议中最简单的一个。

csvtool pastecol 2 2 file1.csv file2.csv

如果您以前尚未安装 csvtool,则必须安装sudo apt-get install csvtool

来自文档:

pastecol <column-spec1> <column-spec2> input.csv update.csv

将文件 input.csv 中引用的列的内容替换为 update.csv 中指定的相应列的内容。

例子:

  csvtool pastecol 2-3 1- input.csv update.csv.csv > output.csv

请注意在我们的例子中我们如何替换文件的第二列。

例子

文件1.csv

A,,C,D
A,,C,D
A,,C,D
A,,C,D

文件2.csv

A,B
A,B
A,B
A,B

合并两个文件:

csvtool pastecol 2 2 file1.csv file2.csv
A,B,C,D
A,B,C,D
A,B,C,D
A,B,C,D

您实际上要做的就是将 的第二列粘贴file2.csv为 中的第二列file1.csv

请注意,这也适用于同一个文档。如果您想交换两列,可以使用与 input.csv 和 update.vsc 相同的文件来实现。

csvtool pastecol 2 1 file2.csv file2.csv 
A,A
A,A
A,A 
A,A

答案4

在 Python 中,另一种方法是通过 csv 模块。

script.py

#!/usr/bin/python3
import csv
import sys
file1 = sys.argv[1]
file2 = sys.argv[2]
with open(file2, 'r') as r:
    with open(file1, 'r') as f:
        csv_f = csv.reader(f)
        csv_r = csv.reader(r)
        bar = [linex for linex in csv_r]
        foo = [liney[2:] for liney in csv_f]
        zipped = zip(bar,foo)
        result = [x+y for (x,y) in list(zipped)]
        for i in result:
            print(','.join(i))

要运行上述脚本,

python3 script.py file1 file2

输出:

A,B,C,D
A,B,C,D
A,B,C,D
A,B,C,D

相关内容