我有一个csv文件,其初始逗号字段长度不同,第二个逗号字段长度固定。我试图调整第二个逗号字段长度取决于第一个字段长度,例如(第二个字段的长度)=(15 -(第一个字段的长度))。这将固定逗号的前两个字段的总和。
我尝试通过在逗号和非逗号之间插入空格来创建一些字段分隔符,但是它在所有逗号之间以及BOL/EOL之间产生了空格。
也许有一个解决方案,不需要首先插入空格作为字段分隔符,但我还没有找到一个线程在stackoverflow网站,看起来像它会工作。
例子"myscv"(3行样例):
^,somefilename1,,somefoldername1,n
^,,somefilename2,,somefoldername2,n
^,,,somefilename3,,somefoldername3,n
希望是:
^,somefilename1,,,,,,,,,,,,,,somefoldername1,n
^,,somefilename2,,,,,,,,,,,,,somefoldername2,n
^,,,somefilename3,,,,,,,,,,,,somefoldername3,n
使用sed:
在逗号和非逗号之间创建初始空格字段分隔符sed 's/([,^,])/&/g mycsv
生产:
^ , somefilename1 , , somefoldername1 , n
^ , , somefilename2 , , somefoldername2 , n
^ , , , somefilename3 , , somefoldername3 , n
我已经设法修改行内容,以添加空格作为分隔符使用sed:
sed 's/,,*/&/g">
到第二个管道可以删除换行符处的前导空格:
sed 's/^//g'
仍在寻找一种方法来调整逗号的第二个字段的大小…
给定输入文件
$ cat file
,somefilename1,,somefoldername1,
,,somefilename2,,somefoldername2,
,,,somefilename3,,somefoldername3,
然后,使用awk我们可以移动
周围的字段awk -v total=15 '
BEGIN {FS = OFS = ","}
{
tmp = $(NF - 1)
$(NF - 1) = ""
NF = total
$(total-1) = tmp
print
}
' file
生产
,somefilename1,,,,,,,,,,,,somefoldername1,
,,somefilename2,,,,,,,,,,,somefoldername2,
,,,somefilename3,,,,,,,,,,somefoldername3,
你的描述有点令人困惑(你是什么意思与字段或字段长度?)但基于示例输入/输出我猜这就是你要找的
$ awk -F, -v OFS=, '{for(i=1;i<=NF;i++)
if($i!="") {n=15-i; break}
t=$(NF-1); $(NF-1)=""; NF+=n; $(NF-1)=t}1' file
,somefilename1,,,,,,,,,,,,,,,somefoldername1,
,,somefilename2,,,,,,,,,,,,,,somefoldername2,
,,,somefilename3,,,,,,,,,,,,,somefoldername3,
查找第一个非空字段的位置。根据位置索引,在倒数第二个字段之前添加一定数量的空字段。
这个sed
解决方案利用反向引用,以便从第二组中减去第一组逗号分隔符。
$ sed "s/,+[^,]*,/&$(printf ',%.0s' {1..15})/;s/(,+)([^,]*),,1/12/" input_file
^,somefilename1,,,,,,,,,,,,,,somefoldername1,n
^,,somefilename2,,,,,,,,,,,,,somefoldername2,n
^,,,somefilename3,,,,,,,,,,,,somefoldername3,n
s/,+[^,]*,/&$(printf ',%.0s' {1..15})/;
-收集行开头所有可用的逗号,然后跳转到下一个可用的逗号,并使用printf
插入15个额外的逗号s/(,+)([^,]*),,1/12/
-收集第一个字段中的所有逗号,第一个捕获组在括号内。继续删除固定分隔符,然后减去包含在第一组分隔符中的逗号数量,并使用反向引用1
,通过将它们排除在捕获组括号之外,返回第一个捕获组的缓冲区。
基于awk
的单遍、无循环、无计数、无正则表达式、无数组的解决方案:
{m,g}awk 'NF+=($(___-!_)=$(__=NF-!_))^($__=_)' FS=',' OFS=',' ___=15
or even more concisely
{m,g}awk '($(__-!_)=$--NF ($NF=_))^!++NF' FS=',' OFS=',' __=15
,somefilename1,,,,,,,,,,,,somefoldername1,
,,somefilename2,,,,,,,,,,,somefoldername2,
,,,somefilename3,,,,,,,,,,somefoldername3,