現在、私のファイルには次のセクションが含まれています。
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フラグを使用できます。)