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"
...

私はPHPバージョン(最初のパラメータ)とタスク(2番目のパラメータ)を受け入れる小さなbashスクリプトを準備しています。たとえば、仮想コマンドは次のようになります。

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 inplacetmpファイルを手動で生成する代わりにそれを使用できます。

おすすめ記事