[英]sed digits with optional decimal and backreference
我有這樣的簡單輸入:
11111(n)
222222(p)
33333333(:)
我可以使用 sed backreference 用這樣的數字交換括號:
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
似乎並不具有\\d
速記,如尖stackexchange
你可以使用這個sed
:
sed -E 's/^([.[:digit:]]+)(\([^)]*\))/\2 \1/g' file
(n) 11111
(n) 11111.111
(p) 2222222.22
(:) 33.3333333
這里[.[:digit:]]+
將匹配任何數字或點字符的 1+。
當您知道在 POSIX 括號表達式中使用[:digit:]
匹配什么時,它變得非常簡單。 您需要做的就是包含另一個.
這樣括號表達式將意味着一組數字以及.
,
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
為什么不只使用簡單的集合?
sed -e 's/\([0-9.]*\)\((.*)\)/\2 \1/' file
由於 [0-9] 和 [:digit:]
基本相同
,但是當您想要包含其他字符時,前者更直觀。
再考慮一下,我看到您正在嘗試匹配合法數字,即沒有點或只有一點,因此改進的 sed one 將是:
sed -r 's/([0-9]+(\.[0-9]+)?)(\(.*\))/\3 \1/' file
-r 支持 +? 在 RE 中並切換括號的轉義。
或者使用 perl 來避免所有這些 RE 擴展混淆:
perl -lne 'print "$3 $1" if /(\d+(\.\d+)?)\s*(\(.*?\))/' file
更新:正如 Benjamin W. 在評論中提到的,[0-9] 和 [[:digit:]] 不一樣,所以如果你想考慮其他語言中可能的數字,sed 應該是:
sed -r 's/([[:digit:]]+(\.[[:digit:]]+)?)(\(.*\))/\3 \1/' file
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.