ディレクトリに特定の拡張子を持つファイルの場合は、パターンの後の括弧内のすべての変数の発生回数を計算したいと思います。各ファイルには、複数のレコード/行のパターンを含めることができます。
これまでは、ファイルを処理して結果を配列に保存できますが、処理するすべての新しいファイルが配列を上書きしているようです。配列値を保持する方法は?
#!/bin/bash
for x in `find . $PROGFILES -name "*.fgl"`
do
awk -f <(cat - <<-'EOF'
/ envget | env-get | \"envget\" | \"env-get\" /
{
gsub( /get-env/, "envget") ;# removes hypens
gsub( /.*envget/, " envget")
gsub( "\\concat" ,"") ;# removes concat
gsub( "\\substring" , "") ;# removes substring
for (i = 1; i<= NF; i++) {
if ( substr( $i, 1, 6) == "envget" ) {
lenofget = 8;
} else {
lenofget = 0;
}
if ( lenofget != 0 ) {
gsub("\\envget" , "",$i) ;#removes envget
gsub ( /\)\.*/, "",$i) ;#removes everything after a closing parenthesis
gsub ( /\47/, "",$i) ;#so used octal instead
gsub ( /\(/, "",$i) ;#removes paraentheses
gsub ( /\"/, "",$i) ;#removes double quotes
gsub ( /\,.*/, "",$i) ;#removes everything after a , This is for any concat syntax
gsub ( /[\/].*/, "",$i) ;#removes everything after a forward slash
narr[$i]++
}
}
}
END {
for (y in narr) {
printf("%s - %d\n",y, narr[y])
}
}
EOF
) $x
done
パターン付きファイルの一般的なレコード/行は次のとおりです。
if envget("SYPSDATA") in {SPACES "."}
set lf-path = "envget"('SYPSCTRL')
if env-get(concat("LOG_PRINTER",service-centre)) != spaces
trconcat(env-get("TMPDIR"),"/ps_xxx_temp.psv")
envget(substring(ws-envprinter1,1,strlen(ws-envprinter1)))
set lf-path = "envget"('SYPSCTRL')
display bitmap concat(envget('BTS')'/images/repedge.gif') @19,44
複数のパターン一致行を持つ複数のファイルがあることを考えると、次のような出力を取得したいと思います(ここでは、数字は各ファイルで見つかった合計数です)。
BTS - 15
LOG_PRINTER - 7
ws-envprinter1 - 3
SYPSDATA - 120
TMPDIR - 130
SYPSCTRL - 200
答え1
あなたはやっています
「検索」でxについて。 $PROGFILES - 名前 "*.fgl"` する アッ(awk_プログラム)$x 完璧
awk
各ファイルに対して新しいプロセスを開始します。なぜ?ただ
アッ(awk_プログラム)*.fgl "$PROGFILES"/*.fgl
サブディレクトリを検索する必要がない場合。本当にサブディレクトリを検索する必要がある場合は、少し複雑です。
探す。 "$PROGFILES" - 名前 "*.fgl" -exec awk(awk_プログラム){}+
メモ:
- 妥当な理由がなく、実行している操作を明確に知らない限り、常にシェル変数(および
"$PROGFILES"
)を引用する必要があります。"$x"
これを使用する必要はありません
cat
。 awkプログラムを引用符で囲むことができます:awk ' / envget | env-get | \"envget\" | \"env-get\" / { gsub( /get-env/, "envget") ︙ } ' "$x"
またはファイルに入れて 。
awk -f (awk_program_file)
- コマンドラインサイズに(非常に大きい)制限があるため、上記の方法のいずれも合計数を取得することは保証されていません。結合された名前がその制限を超えるファイルが多すぎると、そのファイルをすべて処理するために複数の
find
プロセスawk
が呼び出され、再度不完全な数が得られます。この問題を解決する1つの方法は、awk
個々の実行の結果を収集して組み合わせることです。
答え2
あなたの試みにいくつかのエラーがあります(自慢しているわけではありません。私たちは皆学ぶためにここにいます!)。
各呼び出しは独自のメモリ空間を持つ別のプロセスなので、ファイルが処理されると、次の呼び出しawk
で配列の値を保持しないのが正常です。awk
繰り返しごとにカウントを出力しfor
、最後に追加の手順を実行してすべてを要約する必要があります。最も簡単な方法は、これらすべてをファイルに追加することです。
#!/bin/bash
echo "" > "$HOME/tmp_count.txt"
for x in `find . $PROGFILES -name "*.fgl"`
do
awk '
/env-?get/ {
for (i = 1; i<= NF; i++) {
if ($i ~ /env-?get/) {
a = gensub(/.*env-?get\"?\((concat\(|substring\()?(\"|\47)?([a-zA-Z0-9\-_]*)(\"|\47)? *(\)|,)?.*/, "\\3", $i)
arr[a]++
}
}
}
END {
for (y in arr) {
printf("%s %d\n",y, arr[y])
}
}
' "$x" >> "$HOME/tmp_count.txt"
done
awk '{arr[$1] += $2}END{for (key in arr) {printf("%s - %d\n", key, arr[key])}}' < "$HOME/tmp_count.txt"
また、あなたの方法が常に動作するわけではないようで、aで大きな正規表現を試してみgensub
ました。私は正規表現ウィザードではないので、場合によっては問題が発生する可能性があります。試してみて、効果があるか教えてください!