简体   繁体   English

SED - 反向匹配模式

[英]SED - reverse matched pattern

I have the following task:我有以下任务:

match all lines which end with a number and then reverse these numbers匹配所有以数字结尾的行,然后反转这些数字

example:例子:

romarana:qwerty12543
asdewfpwk:asdqwe312
asdj:asbd
asdewfpwk:strwtwe129
ooasodo:asbdjahj

should be:应该:

romarana:qwerty34521
asdj:asbd
asdewfpwk:asdqwe213
asdewfpwk:strwtwe921
ooasodo:asbdjahj

What I tried:我尝试了什么:

sed -r "/[0-9]$/s/[0-9]{1,}$/$(rev <<< &)/" test.txt

NOTE: you can ignore lines that don't end with the number for now.注意:您现在可以忽略不以数字结尾的行。

NOTE: You can use awk,grep or any other tool注意:您可以使用 awk、grep 或任何其他工具

With perlperl

$ perl -pe 's/\d+$/reverse $&/e' ip.txt
romarana:qwerty34521
asdewfpwk:asdqwe213
asdj:asbd
asdewfpwk:strwtwe921
ooasodo:asbdjahj

The e modifier allows to use Perl code in replacement section. e修饰符允许在替换部分使用 Perl 代码。 $& contains the matched portion. $&包含匹配的部分。

You can do this with an awk command, as in the following bash script:您可以使用awk命令执行此操作,如以下bash脚本所示:

#!/usr/bin/env sh

(   echo romarana:qwerty12543
    echo asdewfpwk:asdqwe312
    echo asdj:asbd
    echo asdewfpwk:strwtwe129
    echo ooasodo:asbdjahj ) | awk '
        /[0-9]+$/ {                             # Lines ending in digits.
            num = txt = $0                      # Divide into text and num.
            gsub("[0-9]+$", "", txt)
            num = substr(num, length(txt)+1)

            revnum = ""                         # Build reversed number bit.
            while (num != "") {
                revnum = substr(num, 1, 1)""revnum
                num = substr(num, 2)
            }

            print txt""revnum" (from "$0")"     # Output text, reversed num.
            next
        }
        { print }                               # Not digits at end.
    '

It's pretty verbose, and could probably be reduced, but it does the job (you can get rid of the from output, that's just there so you can see it's working):它非常冗长,可能会减少,但它完成了工作(你可以去掉from output,它就在那里,所以你可以看到它正在工作):

pax:~> ./testprog.sh
romarana:qwerty34521 (from romarana:qwerty12543)
asdewfpwk:asdqwe213 (from asdewfpwk:asdqwe312)
asdj:asbd
asdewfpwk:strwtwe921 (from asdewfpwk:strwtwe129)
ooasodo:asbdjahj

This can also be done with sed alone, by inserting a separator character (let's take the number sign) before the number and then repeatedly moving the line's last digit before the separator:这也可以单独使用sed来完成,方法是在数字前插入一个分隔符(让我们使用井号),然后重复移动分隔符前该行的最后一位数字:

sed 's/\([0-9]*\)$/#\1/;:b;s/#\([0-9]*\)\([0-9]\)$/\2#\1/;tb;s/#$//'

With GNU awk could you please try following.使用 GNU awk ,请尝试以下操作。

awk '
match($0,/[0-9]+$/,a){
  num=split(a[0],arr,"")
  for(i=num;i>0;i--){
    val=val arr[i]
  }
  print substr($0,1,RSTART-1) val
  val=""
  next
}
1
' Input_file

Output will be as follows. Output 将如下所示。

romarana:qwerty34521
asdewfpwk:asdqwe213
asdj:asbd
asdewfpwk:strwtwe921
ooasodo:asbdjahj

With GNU awk for the 3rd arg to match() and null FS splitting $0 into chars:使用 GNU awk 将第三个参数match()和 null FS$0拆分为字符:

$ awk -v FS= 'match($0,/(.*[^0-9])([0-9]+)$/,a) {
    $0=a[2]; for (i=NF;i>=1;i--) a[1]=a[1] $i; $0=a[1]
} 1' file
romarana:qwerty34521
asdewfpwk:asdqwe213
asdj:asbd
asdewfpwk:strwtwe921
ooasodo:asbdjahj

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM