-1

内部で awk スクリプトを呼び出すシェル スクリプト プログラムを作成しています。これが私のスクリプトです。

for FILE in `eval echo{0..$fileIterator}`
{

if(FILE == $fileIterator)
{
    printindicator =1;
}
    grep RECORD FILEARRAY[FILE]| awk 'for(i=1;i<=NF;i++) {if($i ~ XXXX) {XARRAY[$i]++}} END {if(printIndicator==1){for(element in XARRAY){print element >> FILE B}}'

私のコードが明確であることを願っています。他に詳細が必要な場合はお知らせください。

問題

このプログラムでの私の動機は、すべてのファイルをトラバースして、すべてのファイルで「XXXX」を含む行を取得し、その行を配列に格納することです。それが私がここでやっていることです。最後に、配列変数の内容をファイルに保存する必要があります。以下のように、各ステップでコンテンツを保存できます

{if($i ~ XXXX) {XARRAY[$i]++; print XARRAY[$i] >> FILE B}}

しかし、このアプローチに行かない理由は、毎回 I/O 操作を行う必要があるためです。これには時間がかかります。そのため、毎回それをインメモリに変換し、最後にインメモリ配列をダンプしています( XARRAY) をファイルに追加します。

ここで私が直面している問題はそれです。シェル スクリプトは awk を毎回呼び出し、データは配列 (XARRAY) に格納されますが、次の反復では、XARRAY の以前の内容が削除され、これが新しい配列と見なされるため、新しい内容が配置されます。したがって、最後にコンテンツを印刷すると、最近更新された XARRAY のみが印刷され、これから期待されるすべてのデータは印刷されません。

予想される提案

1) awk スクリプトに、XARRAY が古いものであり、各反復で毎回呼び出されているときに新しいものではないことを認識させる方法。

2) 別の方法の 1 つは、毎回 I/O を実行することです。しかし、私はこれに興味がありません。これ以外に代替手段はありますか?ありがとうございました。

4

2 に答える 2

0

ああ、それが本物なのか疑似コードなのかわかりません!

awk を保持状態にすることはできません。一時ファイルに保存するか、シェル変数に保存する必要があり、その内容を後の呼び出しに渡します。しかし、これは、あなたが達成したいことを私が理解していることには、あまりにも面倒です。

ループを省略することをお勧めします。これにより、並べ替えを行うだけで awk を 1 回だけ呼び出すことができます。ファイル A はループ内のファイルであり、ファイル B は外部のものであると想定しています。並べ替えは、非常に大まかに次のようになります。

grep RECORD ${FILEARRAY[@]:0:$fileIterator} | awk 'for(i=1;i<=NF;i++) {if($i ~ XXXX) {XARRAY[$i]++}} END {for(element in XARRAY){print element >> FILEB}'

ファイル名の展開をgrep呼び出しに移動し、printIndicator チェック全体を削除しました。

それはすべてさらに効率的に行うことができます (明らかな 1 つは の削除ですgrep)。

編集:更新からの情報でループの反復を修正しました。これは、新しい空白の問題や長すぎるコマンドラインの影響を受けない、ルーピーなソリューションです。

for FILE in $(seq 0 $fileIterator); do
  grep RECORD "${FILEARRAY[$FILE]}"
done | 
awk 'for(i=1;i<=NF;i++) {if($i ~ XXXX) {XARRAY[$i]++}} END {for(element in XARRAY){print element >> FILEB}'

これはまだ 1 回awkだけ実行され、常にループからデータが供給されます。

結果を配列 UGUGU にロードする場合は、以下も実行します (bash 4 が必要です)。

mapfile UGUGU < FILEB
于 2012-07-11T18:35:49.590 に答える
0
results=$(for loop | awk{for(element in XARRAY)print element}).. 

結果を配列として宣言したため、出力されるすべての「要素」について、結果[1]、結果[2]に格納する必要があります。

しかし、これの代わりに、以下を実行しています... element = "I am fine" (for ループの最初の繰り返し)、element = "How are you" (for ループの 2 回目の繰り返し) と仮定しましょう。

これに従った私の期待される結果は、 results[1]= "I am fine" and results[2] = "How are you" ですが、取得している出力は results[1]= "I" results[2] です=「午前」。なぜスペースで区切られているのかわかりません..これに関する提案

于 2012-07-11T20:10:49.933 に答える