在模式之后添加字符串不起作用

时间:2017-06-17 09:17:16

标签: linux bash shell sed grep

我想找到ssh端口并在字符串### SSHPORT_TAG之后添加此端口脚本。

我的剧本:

PORTSSH=$( set | grep "\(SSH_CONNECTION\)" | sed -e "s/^SSH_CONNECTION='//g" | sed -e "s/^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\x20[0-9]*\x20//g" | sed -e "s/^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\x20//g" | sed -e "s/'//g" | grep "[0-9]*")
sed "s/.*SSHPORT_TAG.*/&\nSSHport=$PORTSSH/" rc.firewall

但它不起作用。在调试中我有:

++ grep '[0-9]*'
++ sed -e 's/'\''//g'
++ sed -e 's/^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\x20//g'
++ sed -e 's/^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\x20[0-9]*\x20//g'
++ sed -e 's/^SSH_CONNECTION='\''//g'
++ grep '\(SSH_CONNECTION\)'
++ set
+ PORTSSH='22
    PORTSSH=$( set | grep "\(SSH_CONNECTION\)" | sed -e "s/^SSH_CONNECTION=//g" | sed -e "s/^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\x20[0-9]*\x20//g" | sed -e "s/^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\x20//g" | sed -e "s///g" | grep "[0-9]*");'
+ sed -i '/SSHPORT_TAG/a SSHPORT=22
    PORTSSH=$( set | grep "\(SSH_CONNECTION\)" | sed -e "s/^SSH_CONNECTION=//g" | sed -e "s/^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\x20[0-9]*\x20//g" | sed -e "s/^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\x20//g" | sed -e "s///g" | grep "[0-9]*");' rc.firewall
sed: -e expression #1, char 32: extra characters after command

为什么它不起作用?你在这种情况下帮助我吗?感谢。

1 个答案:

答案 0 :(得分:0)

要回答为什么它不起作用导致错误的行是在问题中的代码部分之后,如下所示:

sed -i '/SSHPORT_TAG/a SSHPORT='"$PORTSSH"

但是PORTSSH并不仅包含22个,而是22个,其次是换行符和其他shell表达式,这些表达方式并不理解。

在评论中与@Cyrus的方向相同,启动子shell,2个grep进程,4个sed进程以及管道来处理变量内容是一个重要的开销。

https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html

${parameter#pattern} # to remove smallest prefix which matches pattern
${parameter##pattern} # to remove longest prefix which matches pattern
${parameter%pattern} # to remove smallest suffix which matches pattern
${parameter%%pattern} # to remove longest suffix which matches pattern
${parameter/pat/repl} # to replace first match with repl
${parameter//pat/repl} # to replace all matches with repl

这里的模式遵循glob模式的规则(*任何字符串,?任何字符)。

否则bash也支持正则表达式

例如

if [[ 127.0.0.1:22 =~ ([0-9]*)\.([0-9]*)\.([0-9]*)\.([0-9]*):([0-9]*) ]]; then 
    printf "<%s> " "${BASH_REMATCH[@]}"
fi