我的输入文件由csv行组成,其中col 1是文件名,其余各行将逐字输出到名称在col 1中给出的文件。
示例输入。
file1,field1, field2, field3
file2,field4,field5,field6
并且我希望file1
包含:
field1,field2,field3
和file2
包含:
field4,field5,field6
但是,每行的第一个字符是逗号开头。
我在命令行上将OFS和FS设置为',',然后我的代码是
{
fn = "dummy/" $1 ".txt"
$1 = ""
print $0 > fn
}
唯一的问题是我在每个文件中都得到一个逗号开头,这显然是第一个字段的占位符被删除了。
正在寻找有关awk解决方案的说明。
答案 0 :(得分:2)
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
或者如果每个输出文件名只有1行,那么您只需要:
awk '{close(out); out="dummy/"$1".txt"; sub(/[^,]*,/,""); print > out}' file
答案 1 :(得分:1)
使用awk,您可以执行另一种技巧:
kent$ awk -F, -v OFS="," '{for(i=1;i<NF;i++)$i=$(i+1);NF--}7' <<<'0,1,2,3'
1,2,3
(文件重定向部分被忽略,因为您显然知道它的工作原理)
答案 2 :(得分:0)
给出:
$ 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}
然后:
cat file{1,2}
field1,field2,field3
field4,field5,field6
我担心这不适用于大于一行的文件,因为awk并非旨在写入要读取的文件。
有了gawk
,一切变得容易了,因为gawk
支持in place file editing
因此,您可以按照惯用的方式进行操作,而不必担心用输出覆盖输入文件:
gawk -F, -v OFS=, -i inplace '{$1="";print substr($0,2,length($0)-1)}' file{1,2}
gawk -F, -v OFS=, -i inplace '{for(i=1;i<NF;i++)$i=$(i+1);NF--}1' file{1,2}
答案 3 :(得分:0)
不规范字段(定界符周围的空格)
$file = "C:\Temp\test.txt"
for ($i=1; $i -le 5; $i++) {
$a = Get-Random -Minimum 10 -Maximum 50
$line = $i.ToString() + "," + $a.ToString()
Add-Content $file $line
}