簡體   English   中英

帶有可選小數和反向引用的 sed 數字

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM