我有一个包含以下行的文本文件:
201174480 11-01-1911 J Student 25-07 11585 2 0 SPOED BEZORGEN 1ST 25,00
320819019 11-01-1911 T. Student 28-07 13561 1 15786986 DESLORATADINE TABL OMH 5MG 60ST 3,60
706059901 11-01-1911 ST Student-Student 30-06 14956 1 15356221 METOPROLOLSUCC RET T 100MG 180ST 12,90-
我想用SED将这一行改为:
201174480 11-01-1911 J Student 25-07 11585 2 0 SPOED BEZORGEN 1ST 25,00
320819019 11-01-1911 T. Student 28-07 13561 1 15786986 DESLORATADINE TABL OMH 5MG 60ST 3,60
706059901 11-01-1911 ST Student-Student 30-06 14956 1 15356221 METOPROLOLSUCC RET T 100MG 180ST -12,90
所以我想交换减号,这样我得到-12,90而不是12,90-与SED。我试过了:
尝试1:
sed 's/\([0-9.]\+\)-/-\1/g' file.txt > file1.txt
尝试2:
sed 's/\([0-9].\+\)-$/-\1/g' file.txt > file1.txt
所以REGEX一定有问题,但我真的不明白。请帮忙。
答案 0 :(得分:1)
您可以使用
sed 's/\([0-9][0-9,.]\+\)-\($\|[^0-9]\)/-\1\2/g'
请参阅online demo
关键是在匹配数字和-
(参见\([0-9][0-9,.]\+\)-
)之后,应该是字符串的一端或非数字(\($\|[^0-9]\)
)。因此,我们现在有2个捕获组,这就是为什么我们需要在替换模式(\2
)中进行第二次反向引用。
我在括号表达式中添加了一个点.
,以防您使用混合数字格式,如果您总是使用逗号作为小数点分隔符,则可以将其删除。
模式详情:
\([0-9][0-9,.]\+\)
- 第1组捕获
[0-9]
- 数字[0-9,.]\+
- 一个或多个数字,逗号或点-
- 字面连字符\($\|[^0-9]\)
- 第2组捕获字符串$
的结尾或非数字([^0-9]
)答案 1 :(得分:1)
在您的示例中,两个文件都相同,但我想我知道您的意思。
对于此特定文件,您希望匹配一个空格,后跟零个或多个数字,后跟一个逗号,后跟至少一个数字,后跟一个破折号, 然后是零行或多行空格到行尾。
然后你想用匹配数字替换匹配数字前面的空格和逗号。这样就可以了:
sed -e 's/ \([0-9]*,[0-9][0-9]*\)- *$/-\1/' <file.txt >file1.txt
答案 2 :(得分:1)
您的第一个正则表达式尝试匹配一串数字和.
,但文本包含逗号,而不是.
。如果您将[0-9.]
替换为[0-9,]
,则会执行您想要的替换,并给出:
sed 's/\([0-9,]\+\)-/-\1/g' file.txt > file1.txt
但是,在这种情况下,它还会用25-07
替换-2507
。我建议你明确地与行尾相匹配:
sed 's/\([0-9,]\+\)-$/-\1/g'
或者,您可以要求匹配包含一个逗号:
sed 's/\([0-9]\+,[0-9]\+\)-$/-\1/g'
如果您使用-r
选项sed
,我也会发现这些内容更容易阅读,这会启用&#34;扩展正则表达式&#34;:
sed -r 's/([0-9]+,[0-9]+)-$/-\1/g'
需要转义更少的特殊字符(另一方面,需要转义更多文字字符,但我发现这种情况往往很少见。)
(旁白:请注意,.
通常表示&#34;任何字符&#34;,但在字符类[.]
内,它意味着&#34;字面意思是.
&# 34;,因为毕竟它具有意味着&#34;任何角色&#34;在那里都会毫无用处。)