2012-01-06 4 views
3

У меня есть плоский файл записей, каждый длиной 33 строки. Мне нужно отформатировать этот файл в спецификациях в шаблоне. Шаблон находится в формате DOS, тогда как исходный файл находится в формате NIX. Шаблон имеет специфический отступ и интервал, который должен соблюдаться. Я думал несколько вариантов:BASH: импортирование данных из плоского файла в шаблон

  • BASH с классическими инструментами Никс: SED, AWK, Grep и т.д. ...
  • BASH с шаблоном инструментария
  • Perl eith шаблон инструментарий
  • Perl

Это в порядке моего знакомства. Вот источник образца запись (формат 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 

На самом деле это говорит «конец файла» в конце каждой записи.

Мысли? Я склонен чрезмерно усложнять ситуацию.

UPDATE2

Фигурные его.

Ответ на этот вопрос ниже. Не стесняйтесь предлагать улучшения.

+0

Может быть, использовать PHP из командной строки? Если все сделано правильно, это дает вам полезный компонент для будущего веб-интерфейса бесплатно ... –

+0

Спасибо за предложение Eugen, но я не буду транслировать этот материал, и я не знаю PHP. – Bubnoff

+0

Когда вы говорите «отформатируйте файл к спецификациям в шаблоне», что именно вы хотите сделать с файлом, содержащим записи? –

ответ

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 " 
     [email protected]<%BRANCH-NAME%>@${_loc_name}@g 
     [email protected]<%BRANCH-ADDR%>@${_loc_strt}@g 
     [email protected]<%BRANCH-CTY%>@${_loc_city}@g 
     [email protected]<%CUST-NAME%>@${_pat_name}@g 
     [email protected]<%CUST-ADDR%>@${_pat_addr}@ 
     [email protected]<%CUST-CTY%>@${_pat_city}@ 
     [email protected]<%BARCODE%>@${_barcode}@g 
     [email protected]<%DATE%>@${_date}@ 
     [email protected]<%TITLE%>@${_title}@ 
     [email protected]<%AUTHOR%>@${_auth}@ 
     [email protected]<%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 
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 

Replace массив фиктивный вход с линии чтения из стандартного ввода с (<>) если ты будешь. (Используйте цикл, читающий строки n, и нажмите его в массив, если это более эффективно). Я просто показал суть, добавляю больше переменных по мере необходимости и пропускаю входные строки, задав undef для переменной 'capture' (как показано).

Теперь просто проинтегрируйте эти переменные в свой текст.

Если линия концы дают вам никакого горя, рассмотреть вопрос об использовании chomp например .:

my @lines = (<>); # just read em all... 
my @cleaned = map { chomp } @lines; 
+0

добавил немного больше подсказок о том, как продвигаться вперед от этого – sehe

+0

Часть шаблона должна быть удалена из кода, чтобы сделать его многоразовым для других шаблонов. Я буду работать с этим. – Bubnoff