0

こんにちは、実際に次のような内容のテキスト ファイルをいじる awk スクリプトを管理しようとしました。

    . [135]Edwards Engineering Pty Ltd
       Quality Structural Steel. Specialising In Fabrication And Steel
       Stairs
       21- 23 Ada Ave, Brookvale NSW 2100
       ph: (02) 9938 5320

 . [269]Diavolo Steel Fabrication
       5 Humeside Drv, Campbellfield VIC 3061
       ph: (03) 9357 7947


       . [40]WH Williams Pty Ltd
       Your Partner For High Quality Custom-Made Metal Products
       Short lead times & unbeatable quality. Make us the first choice for
       your entire sheetmetal laser cutting,bending,welding & more.
       61- 77 Egerton St, Silverwater NSW 2128
       ph: (02) 9647 1277
            [41]www.whwilliams.com.au

などなど..実際には巨大なファイル..そして私がなんとか書いたスクリプトは

awk '$2 ~ /\. \[/{$1=x; print}' RS=\*  FS='\n' OFS='|' Myfile > excel.csv

このコマンドは、テキスト ファイルをレコード区切りの csv ファイルに変換します..しかし、上記のように、上記の例のアドレスの長さはさまざまであり、不規則な形式の csv ファイルを取得しています..

だから私が今したいのは、コマンドを変更して、1.会社のタイトルを1つのセルに入れ、2.説明部分が1つのセルに存在する場合は、存在しない場合はセルを空のままにし、3. 1 つのセルに住所部分 4. 1 つのセルに電話番号 5. 1 つのセルに Web サイト.. 特定のコンポーネントが存在しない場合、そのセルは空のままにする必要があります..

私はLinuxが初めてで、何かを処理しようとしていますが、シェルとawkもかなり新しいです..そうする可能性がある場合は、誰かが私を助けてくれます...

4

3 に答える 3

0

複数の行で区切られた1セットのレコードを〜で区切られた1つの行に変換するロジックを使用しました次に、これの上にロジックを記述して、同じものをcsvファイルに変換できます(これはまだ行っていません)

cat ip_file.txt | tr '\n' '~' | tr '[' '\n'

注 : [ がレコード間に入らないと仮定します。

于 2012-06-15T10:25:36.507 に答える
0

これはやや複雑なシナリオであることを認めなければなりません。複数の行フィールドに対処する必要があり、以下の要件が頭に浮かびます。

  • 各フィールドは複数行にまたがる場合があります
  • 出力には特別な形式が必要です。これはCSV形式、つまりコンマ区切りのテキストです。
  • CSVのエスケープ文字
  • ph:電話番号は で始まり、住所番号は番地で始まるなど、特定のフィールド形式に関するいくつかの仮定

参照用のコード スニペットを次に示します。

#!/usr/bin/awk -f
BEGIN{
    RS="\.\s* \[[0-9]+\]";
    FS="\n";
    OFS=",";
}

function find_next_field_until_regex(regex, i, result){
    result = "";
    for (; i < NF; i++){
        field = $i
        sub(/,/, "\,", field);
        sub(/^[ \t]*/, "", field);
        if (field ~ regex){
            break;
        }
        result = result field;
    }
    printf("%s%s", result, OFS);
    return i;
}

{
    if(NF>1){
        sub(/,/, "\,", $1);
        printf("%s%s", $1, OFS);
        i = 2;
        i = find_next_field_until_regex("^[0-9]+", i); #discription
        i = find_next_field_until_regex("^ph: ", i); #address
        i = find_next_field_until_regex("www\\.", i); #phone
        for (; i < NF; ++i){
            printf("%s", $i);
        }
    }
    printf("\n");
}

gist snippetも確認してください。

于 2012-11-03T09:00:57.393 に答える
0
awk '$1 ~ /\. \[/ {
 sub(/\. \[[0-9]*]/, "", $1)
 if ($2 ~ /^ *[0-9]/) $2 = OFS$2
 n = split($0, a, OFS)
 while (a[3] !~ /^ *[0-9]/)
 {                       
  a[2] = a[2]a[3]
  for (i=3; i<=n; ++i) a[i]=a[i+1]
  --n                              
 }   
 print a[1],a[2],a[3],a[4],a[5] }' RS= FS='\n' OFS='|' Myfile > excel.csv
于 2014-03-28T14:24:25.853 に答える