sedまたはawkを使用してソースコードの特定の部分をコメントアウトまたはコメントアウトする方法

sedまたはawkを使用してソースコードの特定の部分をコメントアウトまたはコメントアウトする方法

現在、私のファイルには次のセクションが含まれています。

code statement1
code statement2
# BEGIN SOMENAME
some code
some other code
# END SOMENAME
code statement n +1
code statement n +1

私がしたいのは、間の内容をコメントアウトすることです。

# BEGIN SOMENAME

そして

# END

だから結局、次のように見えます。

code statement1
code statement2
# BEGIN SOMENAME
# some code
# some other code
# END SOMENAME
code statement n +1
code statement n +1

awkまたはを使用してこれを達成できますかsed?もう一度「コメントする」だけで簡単に元に戻せますか?

私が避けたいのは間違いです。したがって、この行がすでにコメント化されている場合はそのままにしてください。また、「コメント入力」でendとstartの間の行がで始まらない限り、何かを試してはいけません#


考えられる解決策が見つかりました。

awk '
    BEGIN { 
        i=0; 
        line_with_no_comment_found=0 
    }
    
    /^# END/ { 
        m=0;
        if ( line_with_no_comment_found == 1 ) { 
            for (var in a) print "# "a[var] 
        } else { 
            for (var in a) print a[var] 
        }
        delete a;
        i=0;
        line_with_no_comment_found=0;
    }
    
    /^# / { 
        if (m==0) { 
            print 
        } else { 
            a[i++]=$0; 
        }
    }
    
    !/^# / { 
        if (m==0) { 
            print 
        } else { 
            a[i++]=$0; 
            line_with_no_comment_found=1
        }
    }
    
    /^# BEGIN ([a-zA-Z_])([1-9][0-9]*)*/ {
        m=1;
    }
    END { }
'<<EOF

ベストアンサー1

このスクリプトは私にとって効果的です。私はこれをGNU Awk 4.0.1でテストしましたが、Nawkでも動作します。

awk 'BEGIN {
    # action=0: uncomment
    # action=1: comment
    action=0
    in_optional_code_block=0
}
{
    if ($0 ~ /^# BEGIN/) {
        in_optional_code_block=1
    } else if ($0 ~ /^# END/) {
        in_optional_code_block=0
    } else if (in_optional_code_block) {
        if (action) {
            if ($0 !~ /^#/) {
                $0 = "# " $0
            }
        } else {
            if ($0 ~ /^#/) {
                sub(/^# ?/, "")
            }
        }
    }
}
1'

私もそれに付属の小さなシェルスクリプトを書いています:

#!/usr/bin/env sh

syntax_error() {
    echo "Usage: `basename \"$0\"` [comment|uncomment] file" >&2
    exit 1
}

case "$1" in
    0|uncomment) action=0; ;;
    1|comment) action=1; ;;
    *) syntax_error; ;;
esac
shift
if [ -z "$@" ]; then syntax_error; fi

awk 'BEGIN {
    action='$action'
    in_optional_code_block=0
}
{
    if ($0 ~ /^# BEGIN/) {
        in_optional_code_block=1
    } else if ($0 ~ /^# END/) {
        in_optional_code_block=0
    } else if (in_optional_code_block) {
        if (action) {
            if ($0 !~ /^#/) {
                $0 = "# " $0
            }
        } else {
            if ($0 ~ /^#/) {
                sub(/^# ?/, "")
            }
        }
    }
}
1' "$@" > "[email protected]"
if [ $? -eq 0 ]; then mv "[email protected]" "$@"; fi

(GNU Awk 4.1.0以降では、構造体を移動するのではなく、最後に-iフラグを使用できます。)

おすすめ記事