sed 或 awk,用于将逗号字段长度调整为另一个字段长度的函数



我有一个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,

最新更新