我有这样简单的输入:
11111(n)
222222(p)
33333333(:)
我可以使用sed后向引用将括号替换为这样的数字:
sed -e 's/\([[:digit:]]*\)\((.*)\)/\2 \1/' file
产生
(n) 11111
(p) 222222
(:) 33333333
太酷了!
但是像这样可能的十进制数字使事情变得更加困难
11111(n)
11111.111(n)
2222222.22(p)
33.3333333(:)
我尝试了很多命令,例如
sed -e 's/\([[:digit:]]*(\.[[:digit:]]*?)\)\((.*)\)/\2 \1/' file
sed -e 's/\([[:digit:]]*\.?[[:digit:]]*?)\)\((.*)\)/\2 \1/' file
sed -e 's/\([[:digit:]]*\.*[[:digit:]]*)\)\((.*)\)/\2 \1/' file
sed -e 's/\([[:digit:]]*.*[[:digit:]]*)\)\((.*)\)/\2 \1/' file
需要的输出:
(n) 11111
(n) 11111.111
(p) 2222222.22
(:) 33.3333333
请注意,数字可以是任意长(1到n位数字),十进制标记(。)和十进制数字是可选的。
此外,sed
似乎没有stackexchange所指出的\d
速记
答案 0 :(得分:1)
您可以使用此sed
:
sed -E 's/^([.[:digit:]]+)(\([^)]*\))/\2 \1/g' file
(n) 11111
(n) 11111.111
(p) 2222222.22
(:) 33.3333333
此处[.[:digit:]]+
将匹配1+的任何数字或点字符。
答案 1 :(得分:1)
当您知道与[:digit:]
匹配的POSIX括号表达式中的内容时,它将变得非常简单。您需要做的就是添加另一个.
,以便括号表达式将表示数字集以及.
sed 's/\([[:digit:].]*\)\((.*)\)/\2 \1/' file
您也无需提及-e
,因为默认情况下,sed
在BRE(基本正则表达式)模式下运行,而在-E
下,ERE(扩展正则表达式)模式为已启用。 \d
也不是sed
的任何版本(POSIX,GNU或FreeBSD)用来匹配数字的有效正则表达式构造。我想它在PCRE库中受支持,您可以在其中使用perl
perl -lne 'print "$2 $1" if /(\d+\.?\d*).*(\([^)]*\))/' file
答案 2 :(得分:0)
为什么不只使用简单集合?
sed -e 's/\([0-9.]*\)\((.*)\)/\2 \1/' file
由于[0-9]和[:digit:] 基本相同,但是当您要包含其他字符时,前一个字符会更直观。
再想一想,我发现您正在尝试匹配合法数字,即没有分数或只有分数,因此改进的sed将是:
sed -r 's/([0-9]+(\.[0-9]+)?)(\(.*\))/\3 \1/' file
-r是否支持+?在RE中并切换括号的转义。
或使用perl避免所有这些RE扩展名混淆:
perl -lne 'print "$3 $1" if /(\d+(\.\d+)?)\s*(\(.*?\))/' file
更新: 正如本杰明·W。在评论中提到的,[0-9]和[[:digit:]]不相同,因此,如果要考虑其他语言中可能的数字,sed应该是:
sed -r 's/([[:digit:]]+(\.[[:digit:]]+)?)(\(.*\))/\3 \1/' file