使用awk和gensub删除字符串中以“ character + number + S”结尾的部分

时间:2018-10-08 04:45:31

标签: shell design-patterns awk substitution

我的目标是删除结尾处的“ 1S”以及紧接其后的字母,在这种情况下为“ M”。我该如何实现?我的无效代码:

echo "14M3856N61M1S" | gawk '{gensub(/([^(1S)]*)[a-zA-Z](1S$)/, "\\1", "g") ; print $0}'
>14M3856N61M1S

期望的结果应该是

>14M3856N61

一些其他信息。 1.我认为substr在这里不起作用,因为我的实际目标字符串可能有不同的长度。 2.我不希望采用定义特殊定界符的方法,因为它将与“ if”一起用作awk条件操作的一部分,而  定界符已在全局定义。 预先谢谢你!

3 个答案:

答案 0 :(得分:2)

为什么不使用简单的替换来最后匹配1S并匹配前面的任何字符?

echo "14M3856N61M1S" | awk '{sub(/[[:alnum:]]{1}1S$/,"")}1'
14M3856N61M1S

此处[[:alnum:]]对应于POSIX字符类以匹配字母数字字符(数字和字母),而{1}代表仅匹配一个字符。或者,如果您确定在模式characters之前只能发生1S,则将[[:alnum:]]替换为[[:alpha:]]

要回答OP将匹配结果放在单独变量上的问题,请使用match(),因为sub()不会返回被替换的字符串,而只会返回进行替换的次数。

echo "14M3856N61M1S" | awk 'match($0,/[[:alnum:]]{1}1S$/){str=substr($0,1,RSTART-1); print str}'

答案 1 :(得分:2)

编辑: 根据OP的评论,我正在添加一些解决方案,其中OP也可以将结果也放入bash变量中,如下所示。

var=$(echo "14M3856N61M1S" | awk 'match($0,/[a-zA-Z]1S$/){print substr($0,1,RSTART-1)}' )
echo "$var"
14M3856N61


请您也可以尝试以下方法。

echo "14M3856N61M1S" | awk 'match($0,/[a-zA-Z]1S$/){$0=substr($0,1,RSTART-1)} 1'
14M3856N61

上述命令的说明:

echo "14M3856N61M1S" |        ##printing sample string value by echo command here and using |(pipe) for sending standard ouptut of it as standard input to awk command.
awk '                         ##Starting awk command here.
  match($0,/[a-zA-Z]1S$/){    ##using match keyword of awk here to match 1S at last of the line along with an alphabet(small or capital) before it too.
   $0=substr($0,1,RSTART-1)   ##If match found in above command then re-creating current line and keeping its value from 1 to till RSTART-1 value where RSTART and RLENGTH values are set by match out of the box variables by awk.
  }                           ##Closing match block here.
1'                            ##Mentioning 1 will print the edited/non-edited values of lines here.

答案 2 :(得分:1)

echo "14M3856N61M1S" | awk -F '.1S$' '{print $1}'

输出:

14M3856N61