ブラケットが適切に配置されているかどうかを確認する awk のスクリプトを探しています。使用される括弧は {} [] および () です。すべての括弧は閉じる必要があり、括弧を混在させることはできません。不正な例: ( [ ) ]
2 に答える
あなたがやろうとしていることが汎用言語に当てはまる場合、これは重要な問題です。
まず、コメントと文字列について心配する必要があります。正規表現を使用するプログラミング言語でこれを確認したい場合、これはあなたの探求をさらに困難にします.
ですから、あなたの質問についてアドバイスをする前に、あなたの問題領域の限界を知る必要があります. 心配する文字列、コメント、正規表現がないことを保証できる場合、またはより一般的には、バランスが取れていることを確認している用途以外にブラケットを使用できるコードのどこにもない場合、これは生活をよりシンプルに。
チェックしたい言語を知っていると役に立ちます。
ノイズがない、つまりすべてのブラケットが有用なブラケットであるという仮説を立てると、私の戦略は反復的になります。
すべての内側の括弧のペア、つまり内部に括弧を含まないペアを探して削除するだけです。これは、すべての行を 1 つの長い行に折りたたむことによって行うのが最適です (その情報を取得する必要がある場合は、行参照を追加するメカニズムを見つけます)。この場合、検索と置換は非常に簡単です。
配列が必要です:
B["("]=")"; B["["]="]"; B["{"]="}"
そして、それらの要素をループします:
for (b in B) {gsub("[" b "][^][(){}]*[" B[b] "]", "", $0)}
私のテストファイルは次のとおりです。
#!/bin/awk
($1 == "PID") {
fo (i=1; i<NF; i++)
{
F[$i] = i
}
}
($1 + 0) > 0 {
count("VIRT")
count("RES")
count("SHR")
count("%MEM")
}
END {
pintf "VIRT=\t%12d\nRES=\t%12d\nSHR=\t%12d\n%%MEM=\t%5.1f%%\n", C["VIRT"], C["RES"], C["SHR"], C["%MEM"]
}
function count(c[)
{
f=F[c];
if ($f ~ /m$/)
{
$f = ($f+0) * 1024
}
C[c]+=($f+0)
}
私の完全なスクリプト (行参照なし) は次のとおりです。
cat test-file-for-brackets.txt | \
tr -d '\r\n' | \
awk \
'
BEGIN {
B["("]=")";
B["["]="]";
B["{"]="}"
}
{
m=1;
while(m>0)
{
m=0;
for (b in B)
{
m+=gsub("[" b "][^][(){}]*[" B[b] "]", "", $0)
}
};
print
}
'
そのスクリプトの出力は、ブラケットの最も内側の不正な使用で停止します。ただし、注意してください: 1/ このスクリプトは、コメント、正規表現、または文字列内の括弧では機能しません。2/ 元のファイルのどこに問題があるかを報告しません。3/ すべてのバランスの取れたペアを削除しますが、最も内側で停止します。エラー状態を検出し、すべての englobbing ブラケットを保持します。
ポイント3/はおそらく悪用可能な結果ですが、あなたが考えていたレポートメカニズムについてはわかりません.
ポイント 2/ は比較的簡単に実装できますが、作成には数分以上の作業が必要です。
ポイント1/は、入れ子になった始まりと終わりが競合するまったく新しい領域、または特殊文字の特別な引用ルールに入るからです...
ファイルを文字ごとに読み取る必要があります。見た開き括弧のスタックを構築します。閉じ括弧が表示されたら、一致する開き括弧をスタックからポップするか、括弧が一致しないというエラーを記録できます。
awk は、この仕事に適したツールではありません。汎用スクリプト言語 (Perl/Tcl/etc) を使用します。