構成ファイルセットがあり、その構成行を含むテーマディレクトリ内のすべてのファイルにいくつかの構成をコメントアウトしたいと思います。
構成ファイルは次のとおりです。
...
someconfig = comand()#@#$#$@#
asdbaksdjbkajsbd
asdasdjhavshdjvas
...
だから私はbashスクリプトを使ってこれを行うことにしました。
#!/bin/bash
filename='myconfigfile.conf'
echo Start ...
while IFS= read -r line; do
if [[ $line =~ ^someconfig.* ]]; then
echo "$line"
sed -i 's/$line/\#\$line/g' $filename
fi
done < $filename
このファイルで好ましい出力ライン:
...
#someconfig = comand()#@#$#$@#
# asdbaksdjbkajsbd
# asdasdjhavshdjvas
...
私はこれをPythonにしましたが、あまりにも複雑にすることなくbashスクリプトでできることを確認したかったです。
ブールを使用し、すべてのファイルを繰り返して、次の行が空白以外の文字で始まるかどうかを検出して、すべてのファイルでこれらの行を変更する解決策がありますが、部品を置き換える方法がわからず、私のコードがうまくいかないようです。
どんな助けでも大変感謝します。
答え1
この問題の実装は問題が多く、非効率的です。
ファイルを 1 行ずつ読み込み、sed
入力行からコマンドを設定します。行に正規表現の特殊文字(.^$[]
など)が含まれていると、このコマンドが予期せず動作する可能性があります。
sed
その後、変更する必要がある各行に対してファイル全体を一度に処理する必要があります。入力ファイル全体を繰り返し処理する代わりに、各行を個別に処理できます。
awk
ファイルを処理し、一時出力ファイルを処理するシェルスクリプトラッパーを使用することをお勧めします。 (またはawk
などの内部編集。)sed
perl
#!/bin/bash
filename='myconfigfile.conf'
temp=${filename}.temp
awk '/^[^ ]/ { comment=0 } # stop commenting if line starts with non-space.
/^someconfig/ { comment=1 } # start commenting if line starts with "someconfig"
comment {$0 = "#" $0} # prepend "#" to whole line ($0)
{ print }' $filename > $temp && mv -f $temp $filename || rm -f $temp
オプションでルールを追加できます。
/^[ ]*$/ { comment=0 } # stop commenting on empty line or space only
空白行または空白のみを含む行が表示された場合は、コメントを停止してください。
にはスペースとタブが含まれています[^ ]
。[ ]
スクリプト番号発覚任意のインデント。ゼロ以外の1行"#"
のすべての項目(インデントを含む)の前に追加されます。comment
答え2
シェルはすでにファイルを1行ずつ処理していますが、なぜsedまたはawkを使用するのですか?このようなタスクを実行するために他の多くのプログラムを使用する必要はありません。
[[ $line =~ '^[[:space:]]' ]] || indent=0
if [[ $line =~ ^someconfig.* || $indent ]]
then
echo -n "#"
indent=1
fi
echo "$line"
ループ出力を一時ファイルに送信しmv
(非常に良い)awkの答えに示されているように:
done <$file >$file.tmp && mv $file.tmp $file
私は通常、コマンドが失敗してもこのようなことが起こらないように、名前の変更を&&にリンクすることを好みます。また、誤字があってすみません。私はこの記事を携帯電話で入力しており、携帯電話のキーボードでコーディングするのに苦労しました。 :)