对于这个看似简单的问题感到抱歉,但是花了太长时间试图在任何地方找到解决方案并尝试不同的sed选项。 我只需要在文本文件中用逗号替换所有点,但只需要在两个位置之间。 例如,来自:
1.3.5.7.9
到
1.3,5,7.9
所以,替换。在3至7位之间。 谢谢!
编辑:对不起,我假装简化了问题,但由于我的问题缺乏细节,前三个答案都没有工作,让我更深入一点。重要的一点是在不知道字符串其余部分的情况下,在一个位置间隔中用逗号替换所有点:
Here some text. I don't want to change. 10.000 usd 234.566 usd Continuation text.
More text. No need to change this part. 345 usd 76.433 usd Text going on. So on.
这是一个固定宽度的文本文件,在列中,我需要更改数字的国际格式,用逗号替换点。我只知道我需要搜索并最终替换点的初始和最终位置。显然,并非所有数字都有点(只有超过1000点)。 感谢。
答案 0 :(得分:2)
在澄清问题后重写答案:
仅使用sed
很难处理,但可以使用cut
和paste
等其他标准实用程序进行简化:
$ start=40
$ end=64
$ paste -d' ' <(cut -c -$((start-1)) example.txt) \
> <(cut -c $((start+1))-$((end-1)) example.txt | sed 'y/./,/') \
> <(cut -c $((end+1))- example.txt)
Here some text. I don't want to change. 10,000 usd 234,566 usd Continuation text.
More text. No need to change this part. 345 usd 76,433 usd Text going on. So on.
(>
只表示前一行的继续。<
是真实的。这当然是非常低效的,但在概念上很简单。
我使用了所有+1
和-1
内容来摆脱多余的空间。不确定你是否需要它。
一种纯粹的解决方案(自己动手):
$ sed "s/\(.\{${start}\}\)\(.\{$((end-start))\}\)/\1\n\2\n/;h;s/.*\n\(.*\)\n.*/\1/;y/./,/;G;s/^\(.*\)\n\(.*\)\n\(.*\)\n\(.*\)$/\2\1\4/" example.txt
Here some text. I don't want to change. 10,000 usd 234,566 usd Continuation text.
More text. No need to change this part. 345 usd 76,433 usd Text going on. So on.
GNU sed
:
$ sed -r "s/(.{${start}})(.{$((end-start))})/\1\n\2\n/;h;s/.*\n(.*)\n.*/\1/;y/./,/;G;s/^(.*)\n(.*)\n(.*)\n(.*)$/\2\1\4/" example.txt
Here some text. I don't want to change. 10,000 usd 234,566 usd Continuation text.
More text. No need to change this part. 345 usd 76,433 usd Text going on. So on.
答案 1 :(得分:1)
我试图简化正则表达式,但它更宽容。
echo 1.3.5.7.9 | sed -r "s/^(...).(.).(..)/\1,\2,\3/"
1.3,5,7.9
PS:它不适用于BSD sed。
答案 2 :(得分:1)
$ echo "1.3.5.7.9" |
gawk -v s=3 -v e=7 '{
print substr($0,1,s-1) gensub(/\./,",","g",substr($0,s,e-s+1)) substr($0,e+1)
}'
1.3,5,7.9
答案 3 :(得分:1)
这在纯sed
中相当尴尬。如果您没有严格限制为sed
,我建议您使用其他工具执行此操作。 Ed Morton基于gawk
的解决方案可能是解决这个问题最不尴尬(没有双关语)的方法。
以下是使用sed
执行grunt工作的示例,但为了简单起见,将其包装在bash函数中:
function transform () {
line=$1
start=$2
end=$3
# Save beginning and end of line
front=$(echo $line | sed -e "s/\(^.\{$start\}\).*$/\1/")
back=$(echo $line | sed -e "s/^.\{$end\}//")
# Translate characters
line=$(echo $line | sed -e 'y/\./,/')
# Restore unmodified beginning/end
echo $line | sed -e "s/^.\{$start\}/$front/" -e "s/\(^.\{$end\}\).*$/\1$back/"
}
将此功能称为:
$ transform "1.3.5.7.9" 3 7
1.3,5,7.9
答案 4 :(得分:0)
谢谢大家。 我发现的(不是我的优点)作为简单的解决方案是:
对于固定宽度的文件:
awk -F "" 'OFS="";{for (j=2;j<= 5;j++) if ($j==".") $j=","}'1
将所有点从第2位置更改为第5位。
对于制表符分隔的字段文件:
awk -F'\t' 'OFS="\t" {for (j=2;j<=5;j++) gsub(/\./,",",$j)}'1
将所有点从第2场变为第5场。
希望可以帮助某人:无法想象在开始时它会如此艰难。