-1

小さな問題があります。ファイルの特定の開始文字列に従ってファイルを並べ替える必要があります。たとえば、数字04、05、または06によるこの形式では、次のようになります。

04..............
................
................
05..............
................
................
06..............
................
................ etc.. 

これが私のawkコードです:http://pastebin.com/dLsWkV3q

またはここだけ:

echo "starting...input file"
read file
echo "reading file..."                                                  

echo "... now sorting..."
cat $file | awk '{
if($1=="04"){
print >> "04_file.txt";
}
if($1=="05"){
print >> "05_file.txt";
 }

if($1=="06"){
print >> "06_file.txt";
 }
}'

echo "finished, bye?"
read wait
echo "bye"

目標は、結果として、対応するブロックのみを含む複数のファイルが必要になることです。たとえば、上記の例では、結果として3つのファイルが必要になります。04_file.txt05_file.txtおよび06_file.txt。AND05_file.txtには04ブロックからの行がありません。最終04_file.txtファイルにはこれだけが含まれます:

04..............
................
................

私の問題は、他のブロックも04_file.txtに保存していることです。

私はどんな助けにも感謝します。どうもありがとう

4

1 に答える 1

3

04、05などで始まる行は、異なるブロックを区切る行だけだと思います。

awk '
    BEGIN { mode="unknown" }
    /^04/ { mode="04" }
    /^05/ { mode="05" }
    /^06/ { mode="06" }
          { if (mode != "unknown") print $0 >> sprintf("%s_file.txt", mode)}' < $file

awk基本的にはパターンに応じてアクションを実行する環境です。すべてのパターンアクションステートメントには次の形式があります

pattern { action }

最も単純な形式では、パターンは現在の入力行に一致する正規表現です。BEGINは、入力が読み取られる前に「一致」する特殊なケースであり、入力ファイルが消費された後に実行されるEND「パターン」もあります。

実行awk時に、入力ファイルを1行ずつ読み取り、パターンがその行と一致するすべてのアクションを実行します。上記のコードでmodeは、入力行が()で始まる04、05などの場合に変数が設定されます^。最後の行(パターンなし)はすべての行に一致し、行全体を対応するファイルに書き込むだけです。

これをいくつかの擬似コードに要約してみます。

mode := "unknown"
for each line of input do
    if line starts with 04 then set mode to 04 endif
    if line starts with 05 then set mode to 05 endif
    if line starts with 06 then set mode to 06 endif

    # mode is now either "unknown" if no 04/05/06 pattern has been read
    # from the file yet or holds the most recently read block start (04/05/06)

    if mode is not "unknown" then
        append whole line to file named 'mode'_file.txt
    endif
endfor

さらに詳しく知りたい場合は、manページを参照するか、Webを参照してawk紹介してください。ここでは、上記の例のように現在の入力行に一致させるだけでなく、はるかに多くのことを実行できるパターン部分についても学ぶことができます。


すべてのブロックが2桁(任意の桁)で始まる場合、上記のコードは次のように短縮できます。

awk '
    BEGIN { mode="unknown" }
    /^[[:digit:]][[:digit:]]/ { mode=substr($0, 1, 2) }
          { if (mode != "unknown") print $0 >> sprintf("%s_file.txt", mode)}' < $file
于 2012-08-04T07:12:22.193 に答える