3

それぞれ 33 行の長さのレコードのフラット ファイルがあります。このファイルをテンプレートの仕様に合わせてフォーマットする必要があります。テンプレートは DOS 形式ですが、ソース ファイルは NIX 形式です。テンプレートには、遵守する必要がある特定のインデントと間隔があります。私はいくつかのオプションを考えました:

  • 従来の nix ツールを使用した BASH: sed、awk、grep など...
  • テンプレート ツールキットを使用した BASH
  • Perl eith テンプレート ツールキット
  • パール

これらは、私がよく知っている順です。サンプル ソース レコード (NIX 形式) を次に示します。スペースを節約するために改行の数を減らしました (通常は 33 行)。

JACKSON HOLE SANITARIUM AND REPTILE ZOO
45 GREASY HOLLER LN
JACKSON HOLE, AK   99999


Change Service Requested


BUBBA HOTEP
3 DELIVERANCE RD
MINNEAPOLIS, MN   99998


BUBBA HOTEP 09090909090909

You have a hold available for pickup as of 2012-01-04:

Title: Banjo for Fun and Profit
Author: Williams, Billy Dee
Price: $10 

テンプレートは次のとおりです (DOS 形式 -- 削減された行数 - 通常は 66 行):

     <%BRANCH-NAME%>
     <%BRANCH-ADDR%>
     <%BRANCH-CTY%>


<%CUST-NAME%> <%BARCODE%>
You have a hold available for pickup as of <%DATE%>:

Title: <%TITLE%>
Author: <%AUTHOR%>
Price: <%PRICE%>


             <%CUST-NAME%>
             <%CUST-ADDR%>
             <%CUST-CTY%>

end of file

実際には、各レコードの最後に「ファイルの終わり」と表示されます。

考え?私は物事を過度に複雑にする傾向があります。

更新2

理解した。

私の答えは以下です。遠慮なく改善を提案してください。

4

2 に答える 2

1

手始めとして、ここにヒントがあります:Perlヒアドキュメント(デモとしていくつかの置換を示しています):

#!/usr/bin/perl
use strict;
use warnings;

my @lines = qw/branchname cust_name barcode bogus whatever/; # (<>);

my ($branchname, $cust_name, $barcode, undef, $whatever) = @lines;

print <<TEMPLATE;
     $branchname
     <%BRANCH-ADDR%>
     <%BRANCH-CTY%>


$cust_name $barcode
You have a hold available for pickup as of <%DATE%>:

Title: <%TITLE%>
Author: <%AUTHOR%>
Price: <%PRICE%>


             $cust_name
             <%CUST-ADDR%>
             <%CUST-CTY%>

end of file
TEMPLATE

必要に応じて、ダミー入力配列をstdinから読み取った行に置き換え(<>)ます。(行を読み取るループを使用し、nそれがより効率的である場合は配列にプッシュします)。要点を示し、必要に応じて変数を追加undefし、「capture」変数を指定して入力行をスキップします(図を参照)。

ここで、これらの変数をテキストに補間するだけです。

ラインエンドがあなたに何らかの悲しみを与えている場合は、chomp例えば:を使用することを検討してください。

my @lines = (<>); # just read em all...
my @cleaned = map { chomp } @lines;
于 2012-01-07T00:56:13.903 に答える
0

これは私がこのプロジェクトに使用しているものです。遠慮なく改善を提案するか、より良い解決策を提出してください。

cp $FILE $WORKING # we won't mess with original

NUM_RECORDS=$( grep "^Price:" "$FILE" | wc -l ) # need to know how many records we have 
                                              # counting occurences of end of record r

TMP=record.txt # holds single record, used as temp storage in loop below

# Sanity
# Make sure temp storage exists. If not create -- if so, clear it.
[ ! -f $TMP ] && touch $TMP || cat /dev/null >$TMP

# functions
function make_template () {
    local _file="$1"
    mapfile -t filecontent < "$_file"
    _loc_name="${filecontent[0]}"
    _loc_strt="${filecontent[1]}"
    _loc_city="${filecontent[2]}"
    _pat_name="${filecontent[14]}"
    _pat_addr="${filecontent[15]}"
    _pat_city="${filecontent[16]}"
    _barcode=${filecontent[27]:(-14)} # pull barcode from end of string
    _date=${filecontent[29]:(-11)}    # pull date from end of string
    # Test title length - truncate if necessary - 70 chars.
    _title=$(grep -E "^Title:" $_file)
    MAXLEN=70
    [ "${#_title}" -gt "$MAXLEN" ] && _title="${filecontent[31]:0:70}" || :
    _auth=$(grep -E "^Author:" $_file)
    _price=$(grep -E "^Price:" $_file)
    sed "
        s@<%BRANCH-NAME%>@${_loc_name}@g
        s@<%BRANCH-ADDR%>@${_loc_strt}@g
        s@<%BRANCH-CTY%>@${_loc_city}@g
        s@<%CUST-NAME%>@${_pat_name}@g
        s@<%CUST-ADDR%>@${_pat_addr}@
        s@<%CUST-CTY%>@${_pat_city}@
        s@<%BARCODE%>@${_barcode}@g
        s@<%DATE%>@${_date}@
        s@<%TITLE%>@${_title}@
        s@<%AUTHOR%>@${_auth}@
        s@<%PRICE%>@${_price}@" "$TEMPLATE"
}

####################################
#  MAIN
####################################

for((i=1;i<="$NUM_RECORDS";i++))
do
    sed -n '1,/^Price:/{p;}' "$WORKING" >"$TMP"  # copy first record with end of record
                                                # and copy to temp storage.

    sed -i '1,/^Price:/d' "$WORKING"             # delete first record using EOR regex.
    make_template "$TMP"                        # send temp file/record to template fu
done

# cleanup
exit 0
于 2012-01-10T20:27:41.763 に答える