Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
向shell中的现有数据添加列_Shell_Awk - Fatal编程技术网

向shell中的现有数据添加列

向shell中的现有数据添加列,shell,awk,Shell,Awk,我有一个有三个标题的csv。我想添加一个名为“tag”的额外标题 然而,如上所示,当前的方法是提供垃圾值。如何获得如下输出:- h1,h2,h3,tag a,b,c,TEST1/a.csv d,e,f,TEST1/a.csv 如果标记列包含文件名,那就太好了。我不知道为什么会得到在第三行awk中显示的结果,我也不完全确定要添加的最后一个字段是什么,因为“预期结果”与您提供的代码并不匹配。如果您的目标是在每一行上添加单词“tag”作为最后一个字段,那么以下操作可能会奏效 awk -F, '{$(

我有一个有三个标题的csv。我想添加一个名为“tag”的额外标题

然而,如上所示,当前的方法是提供垃圾值。如何获得如下输出:-

h1,h2,h3,tag
a,b,c,TEST1/a.csv
d,e,f,TEST1/a.csv

如果标记列包含文件名,那就太好了。

我不知道为什么会得到在第三行awk中显示的结果,我也不完全确定要添加的最后一个字段是什么,因为“预期结果”与您提供的代码并不匹配。如果您的目标是在每一行上添加单词“tag”作为最后一个字段,那么以下操作可能会奏效

awk -F, '{$(NF+1)="tag"} 1' OFS=, TEST1/a.csv
它具有以下位:

  • -F,
    将字段分隔符设置为逗号,与CSV兼容
  • $(NR+1)
    在每条记录的末尾添加一个新字段
  • 1
    是“打印当前记录”的缩写
  • OFS=,
    将输出字段分隔符设置为逗号
有几种方法可以构造相同的逻辑,并且都将提供大致相同的结果

这将在BEGIN块中设置输入和输出字段分隔符,并使用字段的添加作为打印行的条件

awk 'BEGIN{FS=OFS=","} $(NF+1)="tag"' TEST1/a.csv
这样就省去了记录的概念,只需在每一行中添加文本

awk '{$0=$0 ",tag"} 1' TEST1/a.csv
等等

一般来说,如果您正在处理字段中的输入,我建议以理解这些字段的方式使用awk,以防您发现自己将来需要操作字段而不是流。如果需要流编辑器,可以使用
sed

sed 's/$/,tag/' TEST1/a.csv
另一方面,如果希望将文件名添加到每行末尾,并且仅在标题中添加文本
标记
,则可以执行以下操作:

awk 'NR==1 {$(NF+1)="tag"} NR>1 {$(NF+1)=FILENAME} 1' FS=, OFS=, TEST1/a.csv
这将生成所显示的结果,文件名位于最终字段中。当然,您可以根据数据的形状进行各种变化。如果您处理的是多个文件,每个文件的第一行都有一个头,您可能需要这样做:

awk 'NR==1 {$(NF+1)="tag";print} FNR==1 {next} NR>1 {$(NF+1)=FILENAME} 1' FS=, OFS=, file1.csv file2.csv ...

这里的不同之处在于,头在第一行被修改并打印,随后文件的第一行被完全跳过。

我不确定为什么会得到在第三行awk中显示的结果,我也不完全确定您希望添加的最后一个字段是什么,因为您的“预期结果”与您提供的代码不匹配。如果您的目标是在每一行上添加单词“tag”作为最后一个字段,那么以下操作可能会奏效

awk -F, '{$(NF+1)="tag"} 1' OFS=, TEST1/a.csv
它具有以下位:

  • -F,
    将字段分隔符设置为逗号,与CSV兼容
  • $(NR+1)
    在每条记录的末尾添加一个新字段
  • 1
    是“打印当前记录”的缩写
  • OFS=,
    将输出字段分隔符设置为逗号
有几种方法可以构造相同的逻辑,并且都将提供大致相同的结果

这将在BEGIN块中设置输入和输出字段分隔符,并使用字段的添加作为打印行的条件

awk 'BEGIN{FS=OFS=","} $(NF+1)="tag"' TEST1/a.csv
这样就省去了记录的概念,只需在每一行中添加文本

awk '{$0=$0 ",tag"} 1' TEST1/a.csv
等等

一般来说,如果您正在处理字段中的输入,我建议以理解这些字段的方式使用awk,以防您发现自己将来需要操作字段而不是流。如果需要流编辑器,可以使用
sed

sed 's/$/,tag/' TEST1/a.csv
另一方面,如果希望将文件名添加到每行末尾,并且仅在标题中添加文本
标记
,则可以执行以下操作:

awk 'NR==1 {$(NF+1)="tag"} NR>1 {$(NF+1)=FILENAME} 1' FS=, OFS=, TEST1/a.csv
这将生成所显示的结果,文件名位于最终字段中。当然,您可以根据数据的形状进行各种变化。如果您处理的是多个文件,每个文件的第一行都有一个头,您可能需要这样做:

awk 'NR==1 {$(NF+1)="tag";print} FNR==1 {next} NR>1 {$(NF+1)=FILENAME} 1' FS=, OFS=, file1.csv file2.csv ...

这里的不同之处在于,页眉在第一行被修改并打印,随后的第一行文件被完全跳过。

通过查看OP的输出,我相信OP需要的是在第一行,它需要将
标记
字符串添加到页眉,并添加文件名和路径的其余行,如果是这种情况,请尝试以下操作。我还处理了输入文件中每一行的控制M
\r
字符

awk 'BEGIN{OFS=","} {gsub(/\r/,"")} FNR==1{print $0,"tag";next} {print $0,FILENAME}' TEST1/a.csv
输出如下

h1,h2,h3,tag
a,b,c,TEST1/a.csv
d,e,f,TEST1/a.csv


如果您想先在输入文件中删除控件M字符,然后运行
awk
命令,然后使用以下命令

tr -d '\r' '' < Input_file > temp_file  &&  mv temp_file Input_file

通过查看OP的输出,我相信OP需要的是第1行,它需要将
标记
字符串添加到标题中,并且应该添加文件名和路径的其余行,如果是这种情况,请尝试以下操作。我还处理了输入文件中每一行的控制M
\r
字符

awk 'BEGIN{OFS=","} {gsub(/\r/,"")} FNR==1{print $0,"tag";next} {print $0,FILENAME}' TEST1/a.csv
输出如下

h1,h2,h3,tag
a,b,c,TEST1/a.csv
d,e,f,TEST1/a.csv


如果您想先在输入文件中删除控件M字符,然后运行
awk
命令,然后使用以下命令

tr -d '\r' '' < Input_file > temp_file  &&  mv temp_file Input_file

这真的是一个令人讨厌的问题吗?是否值得更新您的标签?另外,您是否在Windows中生成了输入文件?如果是这样的话,请确认您使用的是unix行结束符而不是Windows行结束符。另外,您的输入和输出是这样的吗?行首有空格吗?为什么第一个命令在每行的开头显示四个空格,而最后一个awk命令显示五个空格?你是对的问题可能是由于windows行的结尾。这真的是一个awk问题吗?是否值得更新您的标签?另外,您是否在Windows中生成了输入文件?如果是这样的话,请确认您使用的是unix行结束符而不是Windows行结束符。另外,您的输入和输出是这样的吗?将空格放在