gpt4 book ai didi

linux - 使用 Awk 根据 csv 文件中的分隔符将一列拆分为两列?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:12:31 25 4
gpt4 key购买 nike

我是 shell 脚本的新手。我有一个包含 15000 行和 15 列的 csv 文件“a.csv”。它有一列名为“id_data”

它始终是 a.csv 文件中的第 3 列。

此数据集中的值如下所示:

A,B,id_data,C,D,E,F,...
a,b,12345_85485,c,d,e,f,...
a,b,45786_456322,c,d,e,f,...
a,b,12345_325489,c,d,e,f,...
a,b,_45230_14693,c,d,e,f....

其中 a-f 列的数据范围从数字到日期、字符串、链接。

我想计算第 3 列中 '_' 符号后的唯一值。

为此,我想根据 _ 之前的数字和 _ 之后的数字将此列拆分为两个不同的列,即“ID1 数据”和“ID2 数据”。拆分不是强制性的。主要目的是计算第 3 列中 '_' 之后的唯一数字。

csv 文件中的输出应如下所示:

A,B,ID1 Data,ID2 Data,D,E,F...
a,b,12345,85485,d,e,f,...
a,b,45786,456322,d,e,f,...
a,b,12345,325489,d,e,f,...
a,b,45230,4693,d,e,f,...

我已经尝试使用以下命令来完成它:

cat a.csv | sed -Ee 's/(.*)id_data/\1ID1 Data ID2 Data/' -e 's/,[_ ]/,/' -e 's/_/,/'

它按要求打印了输出。但是 csv 文件的列没有变化。打印的 o/p 看起来像 a,b,12345,85485,c,d,e,f,...

如何将更改应用于 csv 文件中的列?任何意见将是有益的。谢谢

*请注意,开头可能有空格甚至'_'。

最佳答案

能否请您尝试以下操作,这是一个通用解决方案,我们不需要在解决方案中对字段值进行硬编码,它将查找字符串 id_data第一行中的获取其列号并相应地对 Input_file 的其余行执行操作。

awk 'FNR==1{for(j=1;j<=NF;j++){if($j=="id_data"){field=j;$j="ID1_data ID2_data"}};print;next} {sub(/^_/,"",$field); sub(/_/,OFS,$field)} 1' Input_file

添加非单线性形式的解决方案:

awk '
FNR==1{
for(j=1;j<=NF;j++){
if($j=="id_data"){
field=j
$j="ID1_data ID2_data"
}
}
print
next
}
{
sub(/^_/,"",$field)
sub(/_/,OFS,$field)
}
1
' Input_file

注意:请添加 BEGIN{FS=OFS=","}在上面的代码中,如果您的 Input_file 以逗号分隔。

解释:

awk '                                ##Starting awk program here.
FNR==1{ ##Checking condition if FNR==1 which will be TRUE for 1st line.
for(j=1;j<=NF;j++){ ##Started a for loop from j=1 to till value of NF here.
if($j=="id_data"){ ##Checking condition if current field is equal to id_data then do following.
field=j ##Setting field variable value to variable j value.
$j="ID1_data ID2_data" ##Setting current field value to string ID1_data space ID2_data here.
}
}
print ##Printing current line.
next ##next will skip all further statements from here.
}
{
sub(/^_/,"",$field) ##Using substitute function to substitute starting _ with NULL in $field, where field is a variable set in first line.
sub(/_/,OFS,$field) ##Using substitute function to substitute _ with OFS for $field field.
}
1 ##Mentioning 1 will print edited/non-edited lines.
' Input_file ##Mentioning Input_file name here.


编辑: 根据 OP 的评论:

awk '
BEGIN{
FS=OFS=","
}
FNR==1{
for(j=1;j<=NF;j++){
if($j=="id_data"){
field=j
$j="ID1_data ID2_data"
}
}
print
next
}
{
sub(/^_/,"",$field)
sub(/.*_/,OFS,$field)
}
1
' Input_file

关于linux - 使用 Awk 根据 csv 文件中的分隔符将一列拆分为两列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58128032/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com