在重复字符之间强加字符

在重复字符之间强加字符

给定一个字符串,如果逗号前面没有字符,并且在每个没有字符的逗号之间,,a,,,b,,,,,我想-在开头强加该字符。意思是结果是-,-,a,-,-,b,-,-,-,-.现在,我已经尝试过:

echo ",,a,,,b,,,," | sed 's/,/,-/g' | sed 's/-\([^,]\)/\1/g' | sed 's/^,/-&/g'

导致:-,-,a,-,-,b,-,-,-,-

但问题是,调用 sed 3 次效率很低非常长的迭代有没有办法用 sed 来做到这一点,可能使用正则表达式,或任何其他工具调用一次

答案1

(echo ,,a,,,b,,,,; echo a,,b) | perl -pe 's/(^|,)\K(?=(,|$))/-/g' 
-,-,a,-,-,b,-,-,-,-
a,-,b

我想我应该学习sed这些年之一。

答案2

这样做的方法sed是使用循环:

$ echo ",,a,,,b,,,," | sed ':a; s/\(^\|,\)\(,\|$\)/\1-\2/; ta'
-,-,a,-,-,b,-,-,-,-

如果您的版本支持扩展正则表达式,您可以将其简化为更具可读性

sed -E ':a; s/(^|,)(,|$)/\1-\2/; ta'

另一种方法是在 中执行此操作perl,拆分为逗号分隔的字段,然后将空字段映射到连字符:

perl -anle 'print join ",", map { $_ ? $_ : "-" } split(",", $_, -1)'

(强制包含尾随空字段的附加-1参数)。split

答案3

echo ",,a,,,b,,,," |
  awk -v 'FS=,' -v 'OFS=,' '{for (i=1; i<=NF; i++) sub(/^$/,"-",$i); print};'

答案4

$ echo ',,a,,,b,,,,' | sed 's/\(\([^,]\+,\)*\),/\1-,/g; s/\(^\|,\)$/\1-/'
-,-,a,-,-,b,-,-,-,-

第二个表达式(s/\(^\|,\)$/\1-/) 是必需的,只是因为sed当它到达模式空间的末尾时似乎停止匹配,即使$如果唯一的表达式是 ,它仍然可以匹配 a s/\(\([^,]\+,\)*\)\(,\|$\)/\1-\3/g

当然,sed -E这使它更具可读性,但在其他方面是等效的:

sed -E 's/(([^,]+,)*),/\1-,/g; s/(^|,)$/\1-/'

相关内容