Shell 使用awk和gensub删除以“结束”的字符串中的零件;字符+;编号+;S";

Shell 使用awk和gensub删除以“结束”的字符串中的零件;字符+;编号+;S";,shell,design-patterns,awk,substitution,Shell,Design Patterns,Awk,Substitution,我的目标是删除结尾“1”以及它前面的字母,在本例中是“M”。我如何做到这一点?我的非工作代码: echo "14M3856N61M1S" | gawk '{gensub(/([^(1S)]*)[a-zA-Z](1S$)/, "\\1", "g") ; print $0}' >14M3856N61M1S 预期的结果应该是 >14M3856N61 这里有一些附加信息。1.我认为substr在这里不起作用,因为我的实际目标字符串具有不同的长度。2.我不喜欢采用定义特殊分隔符的方法,因为

我的目标是删除结尾“1”以及它前面的字母,在本例中是“M”。我如何做到这一点?我的非工作代码:

echo "14M3856N61M1S" | gawk '{gensub(/([^(1S)]*)[a-zA-Z](1S$)/, "\\1", "g") ; print $0}'
>14M3856N61M1S
预期的结果应该是

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

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

echo "14M3856N61M1S" | awk '{sub(/[[:alnum:]]{1}1S$/,"")}1'
14M3856N61M1S
这里,
[[:alnum:]
对应POSIX字符类以匹配字母数字字符(数字和字母),而
{1}
表示仅匹配一个字符。或者,如果您确定在模式
1S
之前只能出现
字符
,请将
[[:alnum:]
替换为
[:alpha:]

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

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

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

echo "14M3856N61M1S" | awk '{sub(/[[:alnum:]]{1}1S$/,"")}1'
14M3856N61M1S
这里,
[[:alnum:]
对应POSIX字符类以匹配字母数字字符(数字和字母),而
{1}
表示仅匹配一个字符。或者,如果您确定在模式
1S
之前只能出现
字符
,请将
[[:alnum:]
替换为
[:alpha:]

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

echo "14M3856N61M1S" | awk 'match($0,/[[:alnum:]]{1}1S$/){str=substr($0,1,RSTART-1); print str}'
编辑:根据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
上述命令说明:

编辑:根据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
上述命令说明:

输出:

14M3856N61
输出:

14M3856N61

echo“14M3856N61M1S”| sed's/.1S$/'
@Cyrus,谢谢。我更喜欢awk解决方案,因为我正在将其应用于带有条件操作的awk脚本的一部分。看起来您希望
[^(1S)]
能做一些它不能做的事情。它匹配的单个字符不是
1
S
。可能重复
echo“14M3856N61M1S”| sed'S/.1S$/'
@Cyrus,谢谢。我更喜欢awk解决方案,因为我正在将其应用于带有条件操作的awk脚本的一部分。看起来您希望
[^(1S)]
能做一些它不能做的事情。它匹配的单个字符不是
1
S
。这可能是我自己想到的第一件事。我不喜欢定义分隔符,因为它已经在整个awk代码中全局定义。感谢您花时间回复。使用自己的数组和分隔符:
echo“14M3856N61M1S”| awk'{split($1,a,“.1S$”);打印[1]}'
一个简洁的解决方案。凉的非常感谢。这也是我想到自己的第一件事。我不喜欢定义分隔符,因为它已经在整个awk代码中全局定义。感谢您花时间回复。使用自己的数组和分隔符:
echo“14M3856N61M1S”| awk'{split($1,a,“.1S$”);打印[1]}'
一个简洁的解决方案。凉的非常感谢。这确实非常接近我试图实现的目标。非常感谢!@我正在学习如何做到这一点。现在明白了。这确实非常接近我试图实现的目标。非常感谢!@我正在学习如何做到这一点。现在明白了。