unix – sed / awk或其他:one-liner将数字增加1,保持间距字符
编辑:我事先不知道我的数字将在哪个“列”,我想要一个单行.显然sed不做算术,所以也许基于awk的单线程解决方案?
我有一个字符串:(注意间距) eh oh 37 我希望它成为: eh oh 36 (所以我想保持间距) 使用awk我找不到怎么做,到目前为止我有: echo "eh oh 37" | awk '$3>=0&&$3<=99 {$3--} {print}' 但这给了: eh oh 36 (丢失的间距字符,因为字段分隔符是”) 有没有办法问awk类似“使用与输入完全相同的字段分隔符打印输出”? 然后我尝试了其他东西,使用awk的sub(..,..)方法: ' sub(/[0-9][0-9]/,...) {print}' 但是还没有雪茄:我不知道如何引用正则表达式并在第二个参数中对其进行算术运算(我现在用’…’留下). 然后我尝试用sed,但在此之后卡住了: echo "eh oh 37" | sed -e 's/([0-9][0-9])/.../' 我可以使用对匹配数字的引用从sed进行算术运算,并且输出不会修改间距字符数吗? 请注意,这与我关于Emacs的问题以及如何将其应用于某些(大)Emacs区域(使用Emacs的shell-command-on-region的替换区域)有关,但这不是一个相同的问题:这个问题具体是关于如何使用awk / sed / etc时“保留空格”. 解决方法
这是ghostdog74的答案的变体,不需要将数字锚定在字符串的末尾.这是使用匹配而不是依赖于特定位置的数字来完成的.
这将替换第一个数字,其值减去1: $echo "eh oh 37 aaa 22 bb" | awk '{n = substr($0,match($0,/[0-9]+/),RLENGTH) - 1; sub(/[0-9]+/,n); print }' eh oh 36 aaa 22 bb 使用gsub而不是sub将用“36”替换“37”和“22”.如果线路上只有一个号码,那么您使用哪个号码无关紧要.但是,通过这种方式,它将处理带有尾随空格的数字以及可能存在的其他非数字字符(在某些空格之后). 如果你有gawk,你可以使用这样的gensub来挑选字符串中的任意数字(只需设置其值): $echo "eh oh 37 aaa 22 bb 19" | awk -v which=2 'BEGIN { regex = "([0-9]+)>[^0-9]*"; for (i = 1; i < which; i++) {regex = regex"([0-9]+)>[^0-9]*"}} { match($0,regex,a); n = a[which] - 1; # do the math print gensub(/[0-9]+/,n,which) }' eh oh 37 aaa 21 bb 19 第二个(= 2)数字从22变为21.并且嵌入的空间被保留. 它在多行上分解,以便于阅读,但它是复制/可管理的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |