Bash 脚本:添加/删除匹配行上的注释

Bash 脚本:添加/删除匹配行上的注释

我有一个~/.zshrc包含以下几行的文件

...
#export PATH="/usr/local/opt/[email protected]/bin:$PATH"
#export PATH="/usr/local/opt/[email protected]/sbin:$PATH"
##export PATH="/usr/local/opt/[email protected]/bin:$PATH"
##export PATH="/usr/local/opt/[email protected]/sbin:$PATH"
#export PATH="/usr/local/opt/[email protected]/bin:$PATH"
#export PATH="/usr/local/opt/[email protected]/sbin:$PATH"
#export PATH="/usr/local/opt/[email protected]/bin:$PATH"
#export PATH="/usr/local/opt/[email protected]/sbin:$PATH"
export PATH="/usr/local/opt/[email protected]/bin:$PATH"
export PATH="/usr/local/opt/[email protected]/sbin:$PATH"
...

我正在准备一个小的 bash 脚本,它接受 PHP 版本(第一个参数)和操作(第二个参数)。例如虚拟命令可能如下所示:

mycommand 7.4 comment

这只会注释掉文件中的以下几行:

#export PATH="/usr/local/opt/[email protected]/bin:$PATH"
#export PATH="/usr/local/opt/[email protected]/sbin:$PATH"

如果你跑

mycommand 7.1 uncomment

将仅更新以下行:

export PATH="/usr/local/opt/[email protected]/bin:$PATH"
export PATH="/usr/local/opt/[email protected]/sbin:$PATH"

所以我的问题是如何使用sed.sh 脚本中的命令或任何其他命令来解析文件。
我的 bash 脚本如下所示(不起作用)

# File mycommand.sh
# ...
if [[ ! -z "$1" && ! -z "$2" && "$2" = "comment" ]]; then
    # remove multi # comments if there's any
    sed -i '' 's/#*export PATH="\/usr\/local\/opt\/php@$1/export PATH="\/usr\/local\/opt\/php@$1/g'   
    # Finally add a single # comment
    sed -i '' 's/*export PATH="\/usr\/local\/opt\/php@$1/#export PATH="\/usr\/local\/opt\/php@$1/g'    
fi
if [[ ! -z "$1" && ! -z "$2" && "$2" = "uncomment" ]]; then
    # remove one or more # comments
    sed -i '' 's/#*export PATH="\/usr\/local\/opt\/php@$1/export PATH="\/usr\/local\/opt\/php@$1/g'   
fi

答案1

这将稳健、高效且可移植地工作:

#!/usr/bin/env bash

infile=~/.zshrc
tmp=$(mktemp) || exit 1

awk -v ver="$1" -v cmd="$2" '
    index($0,"php@"ver"/") {
        if      ( cmd == "comment" )   { sub(/^#*/,"#") }
        else if ( cmd == "uncomment" ) { sub(/^#+/,"")  }
        else { printf "bad cmd: %s\n", cmd | "cat>&2" }
    }
    { print }
' "$infile" > "$tmp" && mv "$tmp" "$infile"

如果需要,请更改"php@"ver"/""export PATH=\"/usr/local/opt/php@"ver"/"以避免与真实输入中存在但未在示例中显示的其他行发生错误匹配。

如果您有 GNU awk,您可以使用它-i inplace而不是手动创建 tmp 文件。

答案2

您使用的脚本应更改如下:

if [[ ! -z "$1" && ! -z "$2" && "$2" = "comment" ]]; then
    # remove multi # comments if there's any
    sed -i "s/#*export PATH=\"\/usr\/local\/opt\/php@$1/export PATH=\"\/usr\/local\/opt\/php@$1/g" ~/.zshrc
    # Finally add a single # comment
    sed -i "s/export PATH=\"\/usr\/local\/opt\/php@$1/#export PATH=\"\/usr\/local\/opt\/php@$1/g" ~/.zshrc
fi
if [[ ! -z "$1" && ! -z "$2" && "$2" = "uncomment" ]]; then
    # remove one or more # comments
   sed -i "s/#*export PATH=\"\/usr\/local\/opt\/php@$1/export PATH=\"\/usr\/local\/opt\/php@$1/g" ~/.zshrc
fi

问题是:

  1. 后面的空单引号 ( '') sed -i

  2. 您没有指定sed输入文件 ( ~/.zshrc)。

  3. 您需要使用双引号 ( ") 而不是单引号 ( '),以便 shell$1首先扩展变量。看相关问题。

相关内容