使用 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
我的目标是删除结尾的“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