awk-删除了一个字段,但可以';我无法摆脱它';s分隔符

awk-删除了一个字段,但可以';我无法摆脱它';s分隔符,awk,Awk,我的输入文件由csv行组成,其中第1列是文件名,其余的行将逐字输出到第1列中给出名称的文件 示例输入 file1,field1, field2, field3 file2,field4,field5,field6 我希望file1包含: field1,field2,field3 field4,field5,field6 和file2以包含: field1,field2,field3 field4,field5,field6 但是每行的第一个字符是一个前导逗号 我在命令行上将OFS和FS

我的输入文件由csv行组成,其中第1列是文件名,其余的行将逐字输出到第1列中给出名称的文件

示例输入

file1,field1, field2, field3
file2,field4,field5,field6
我希望
file1
包含:

field1,field2,field3
field4,field5,field6
file2
以包含:

field1,field2,field3
field4,field5,field6
但是每行的第一个字符是一个前导逗号

我在命令行上将OFS和FS设置为“”,然后我的代码是

{
  fn = "dummy/" $1 ".txt" 
  $1 = ""
  print $0 > fn 
}
唯一的问题是,每个文件都有一个前导逗号输出,显然第一个字段的占位符被删除了

正在寻找您的awk解决方案的解释。

给出:

$ cat file{1,2}
file1,field1,field2,field3
file2,field4,field5,field6
您可以使用
cut
和Bash循环:

for fn in file{1,2}; do
    cut -d "," -f 2- "$fn" >tmp_file && mv tmp_file "$fn"
done  

$ cat file{1,2}
field1,field2,field3
field4,field5,field6
对于
awk
,经典的习惯用法是:

awk '{$1=""}1' input | awk '{$1=$1}1' > output
但那是行不通的。我想你可以做到:

awk -F, -v OFS=, '{fn=$1; $1=""; print substr($0,2,length($0)-1)>fn}' file{1,2}
然后:

我担心的是,这将无法处理大于一行的文件,因为awk不是设计用来写入它正在读取的文件的


由于
gawk
支持

因此,您可以用惯用的方法来完成,而不用担心用输出覆盖输入文件:

gawk -F, -v OFS=, -i inplace '{$1="";print substr($0,2,length($0)-1)}' file{1,2} 
这也非常适用于的:

gawk-F,-v of s=,-i在{for(i=1;i给定:

您可以使用
cut
和Bash循环:

for fn in file{1,2}; do
    cut -d "," -f 2- "$fn" >tmp_file && mv tmp_file "$fn"
done  

$ cat file{1,2}
field1,field2,field3
field4,field5,field6
对于
awk
,经典的习惯用法是:

awk '{$1=""}1' input | awk '{$1=$1}1' > output
但那不行。我想你可以:

awk -F, -v OFS=, '{fn=$1; $1=""; print substr($0,2,length($0)-1)>fn}' file{1,2}
然后:

我担心的是,这将无法处理大于一行的文件,因为awk不是设计用来写入它正在读取的文件的


由于
gawk
支持

因此,您可以用惯用的方法来完成,而不用担心用输出覆盖输入文件:

gawk -F, -v OFS=, -i inplace '{$1="";print substr($0,2,length($0)-1)}' file{1,2} 
这也非常适用于的:


gawk-F,-vofs=,-i在{for(i=1;i中使用awk,您可以使用另一个技巧:

kent$  awk -F, -v OFS="," '{for(i=1;i<NF;i++)$i=$(i+1);NF--}7' <<<'0,1,2,3'
1,2,3

kent$awk-F,-v of s=“,”{for(i=1;i对于awk,您可以使用另一个技巧:

kent$  awk -F, -v OFS="," '{for(i=1;i<NF;i++)$i=$(i+1);NF--}7' <<<'0,1,2,3'
1,2,3

kent$awk-F,-v of s=“,”{for(i=1;i不规范化字段(分隔符周围的空格)

$awk-F'{file=$1;sub($1 FS,”);print>file}文件
$head文件?

==>file1 file2不规范化字段(分隔符周围的空格)

$awk-F'{file=$1;sub($1 FS,”);print>file}文件
$head文件?
==>文件1文件2
请注意,上面的内容将附加到任何预先存在的输出文件中,因此,如果出现问题,请首先对其进行处理,或者对其进行调整以完成工作:

awk '{close(out); out="dummy/"$1".txt"; sub(/[^,]*,/,""); if (seen[out]++) print >> out; else print > out}' file
或者,如果每个输出文件名只有一行,那么您只需要:

awk '{close(out); out="dummy/"$1".txt"; sub(/[^,]*,/,""); print > out}' file
请注意,上面的内容将附加到任何预先存在的输出文件中,因此,如果出现问题,请首先对其进行处理,或者对其进行调整以完成工作:

awk '{close(out); out="dummy/"$1".txt"; sub(/[^,]*,/,""); if (seen[out]++) print >> out; else print > out}' file
或者,如果每个输出文件名只有一行,那么您只需要:

awk '{close(out); out="dummy/"$1".txt"; sub(/[^,]*,/,""); print > out}' file

您可以执行
cat file1 | cut-d“-f 2->tmp_文件和&mv tmp_文件文件1
b如果您的所有行总共有四个字段,您可以
打印$2、$3、$4
,而不是将
$1
设置为
'
并打印
$0
。您显示的输出缺少
..、field2、field3
的前导空格-这是故意的,还是仅仅是edi的一个怪癖你可以做
catfile1 | cut-d”-f 2->tmp_文件和&mv tmp_文件文件1
b如果您的所有行总共有四个字段,您可以
打印$2、$3、$4
,而不是将
$1
设置为
'
并打印
$0
。您显示的输出缺少
..、field2、field3
的前导空格-这是故意的,还是仅仅是edi的一个怪癖将材料添加到问题中?这太棒了。添加到我的答案中。根据POSIX,减少NF的效果是未定义的行为,因此它可以在gawk中执行您想要的操作,但在其他awk中不会执行。@EdMorton每次我读到您的答案/评论时,我都会从您对shell/awk/sed的深刻了解中学习到……谢谢。这太棒了。添加到我的answ中呃。根据POSIX,递减NF的效果是未定义的行为,因此它可以在gawk中执行您想要的操作,但在其他awk中不会执行。@EdMorton每次我阅读您的回答/评论时,我都会从您对shell/awk/sed的深入了解中了解到……谢谢。当$1或FS包含RE元字符时,这种方法将失败,而当有许多输出文件名。当$1或FS包含RE元字符时,这种方法将失败;当有许多输出文件名时,这种方法将在非GNU AWK中失败。