[英]Use sed to find and replace a number following by its successor in bash
我有一個字符串,其中包含多個出現的數字范圍,用逗號分隔,例如,
2-12,59-89,90-102,103-492,593-3990,3991-4930
現在我想刪除所有直接相鄰的范圍並從字符串中刪除它們,即刪除任何形式為-(x),(x+1)
東西,得到這樣的東西:
2-12,59-492,593-4930
誰能想到一種方法來實現這一目標? 老實說,我不會發布任何我嘗試過的東西,因為我的所有嘗試都非常不成功。 對我來說,似乎不可能使用sed實際找到任何形式的東西-(x),(x+1)
,因為這需要對另一個必須屬於的一部分的數字進行操作或比較找到的數字當前正在搜索數字的命令。
如果每個人都同意sed不是這樣做的正確工具,我會采取另一種方式,但我仍然感興趣,如果可能的話。
用awk
awk -F, -v RS="-" -v ORS="-" '$2!=$1+1' file
使用適當的分隔符設置,在第二個字段不是+1時打印記錄。
RS
是記錄分隔符, ORS
是outpout記錄分隔符。
測試:
> awk -F, -v RS="-" -v ORS="-"
'$2!=$1+1' <<< "2-12,59-89,90-102,103-492,593-3990,3991-4930"
2-12,59-492,593-4930
awk解決方案:
awk -F'-' '{ r=$1;
for (i=2; i<=NF; i++) {
split($i, a, ",");
r=sprintf("%s%s", r, a[2]-a[1]==1? "" : FS $i)
}
print r
}' file
-F'-'
- 處理-
(連字符)作為字段分隔符 r
- 結果字符串 split($i, a, ",")
- 通過分隔符將相鄰范圍邊界拆分為數組a
,
a[2]-a[1]==1
- 關鍵條件,反映(x),(x+1)
輸出:
2-12,59-492,593-4930
這可能適合你(GNU sed):
sed -r ' s/^/\n/;:a;ta;s/\n([^-]*-)([0-9]*)(.*,)/\1\n\2\n\2\n\3/;Td;:b;s/(\n.*\n.*)9(_*\n)/\1_\2/;tb;s/(\n.*\n)(_*\n)/\10\2/;s/$/\n0123456789/;s/(\n.*\n[0-9]*)([0-8])(_*\n.*)\n.*\2(.).*/\1\4\3/;:z;tz;s/(\n.*\n[^_]*)_([^\n]*\n)/\10\2/;tz;:c;tc;s/([0-9]*-)\n(.*)\n(.*)\n,(\3)-/\n\1/;ta;s/\n(.*)\n.*\n,/\1,\n/;ta;:d;s/\n//g' file
這種概念驗證sed解決方案迭代地遞增並將一個范圍的結束與另一個范圍的開始進行比較。 如果比較為真,則刪除兩者並重復,否則它將移至下一個范圍並重復,直到比較所有范圍。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.