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

using awk and gensub to remove the part in a string ending with "character+number+S"

我的目标是删除结尾的“1S”及其前面的字母,在本例中为 "M"。我该如何实现?我的非工作代码:

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

想要的结果应该是

>14M3856N61

这里有一些附加信息。 1. 我认为 substr 在这里不起作用,因为我的实际目标字符串会有不同的长度。 2. 我不喜欢采用定义特殊分隔符的方法,因为这将与 "if" 一起用作 awk 条件操作的一部分,而 分隔符已在全局定义。 提前致谢!

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

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

这里的[[:alnum:]]对应POSIX字符,class表示匹配字母数字字符(数字和字母),{1}表示只匹配一个。或者,如果您确定在模式 1S 之前只能出现 characters,请将 [[:alnum:]] 替换为 [[:alpha:]]

要回答 OP 的问题,将匹配结果放在一个单独的变量上,请使用 match(),因为 sub() 不会 return 替换字符串,而只会计算替换次数.

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

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

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


能不能请你也试试看

echo "14M3856N61M1S" | awk 'match([=11=],/[a-zA-Z]1S$/){[=11=]=substr([=11=],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([=12=],/[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.
   [=12=]=substr([=12=],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.
echo "14M3856N61M1S" | awk -F '.1S$' '{print }'

输出:

14M3856N61