Perl BASH:将数据从平面文件导入模板

Perl BASH:将数据从平面文件导入模板,perl,bash,templates,text-processing,template-toolkit,Perl,Bash,Templates,Text Processing,Template Toolkit,我有一个扁平的档案,每个档案有33行长。我需要将此文件格式化为模板中的规格。模板为DOS格式,而源文件为NIX格式。模板有特定的压痕和间距,必须遵守。我想到了几个选择: BASH与经典的nix工具:sed、awk、grep等 带模板工具包的BASH PerlEITH模板工具包 Perl 这些是我熟悉的顺序。下面是一个示例源记录(NIX格式): 我减少了换行以节省空间(通常为33行): 以下是模板(DOS格式--减少行数-通常为66行): 您在以下日期有一个可供提取的等待: 标题: 作者:

我有一个扁平的档案,每个档案有33行长。我需要将此文件格式化为模板中的规格。模板为DOS格式,而源文件为NIX格式。模板有特定的压痕和间距,必须遵守。我想到了几个选择:

  • BASH与经典的nix工具:sed、awk、grep等
  • 带模板工具包的BASH
  • PerlEITH模板工具包
  • Perl
这些是我熟悉的顺序。下面是一个示例源记录(NIX格式): 我减少了换行以节省空间(通常为33行):

以下是模板(DOS格式--减少行数-通常为66行):


您在以下日期有一个可供提取的等待:
标题:
作者:
价格:
文件结束
实际上,它在每条记录的末尾都会显示“文件结束”

想法?我倾向于把事情复杂化

更新2

我明白了


我的答案如下。欢迎提出改进建议。

作为初学者,这里有一个提示:Perl here文档(作为演示仅显示一些替换):


这就是我在这个项目中使用的。请随时提出改进建议,或提交更好的解决方案

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
cp$FILE$WORKING#我们不会弄乱原始文件
NUM_RECORDS=$(grep“^Price:$FILE”| wc-l)#需要知道我们有多少条记录
#记录结束时的计数发生率r
TMP=record.txt#保存单个记录,用作下面循环中的临时存储
#理智
#确保临时存储存在。如果不创建,则清除它。
[!-f$TMP]&触摸$TMP | | cat/dev/null>$TMP
#功能
函数make_模板(){
本地_文件=“$1”
mapfile-t文件内容<“$\u文件”
_loc_name=“${filecontent[0]}”
_loc_strt=“${filecontent[1]}”
_loc_city=“${filecontent[2]}”
_pat_name=“${filecontent[14]}”
_pat_addr=“${filecontent[15]}”
_pat_city=“${filecontent[16]}”
_条形码=${filecontent[27]:(-14)}#从字符串末尾提取条形码
_date=${filecontent[29]:(-11)}从字符串末尾提取日期
#测试标题长度-必要时截断-70个字符。
_title=$(grep-E“^title:$\u文件)
MAXLEN=70
[“${#u title}”-gt“$MAXLEN”]&&&&_title=“${filecontent[31]:0:70}”|
_auth=$(grep-E“^Author:$\u文件)
_价格=$(grep-E“^price:$\u文件)
sed“
s@${u loc\u name}@g
s@${u loc\u strt}@g
s@${u loc\u city}@g
s@${u pat\u name}@g
s@${u pat\u addr}@
s@${U pat_city}@
s@${U条形码}@g
s@${U日期}@
s@${U title}@
s@${u auth}@
s@${U price}@“$TEMPLATE”
}
####################################
#主要
####################################
对于((i=1;i“$TMP”#复制第一条记录并结束记录
#并复制到临时存储器。
sed-i'1,/^Price:/d'$WORKING“#使用EOR正则表达式删除第一条记录。
制作模板“$TMP”#向模板fu发送临时文件/记录
完成
#清理
出口0

也许可以从命令行使用PHP?如果操作正确,它将免费为您提供一个可恢复的组件,用于未来的web界面……感谢Eugen的建议,但我不会将这些东西webify,我也不知道PHP。当您说
将文件格式化为模板中的规范时
您希望对包含记录的文件做什么?我需要格式化记录以匹配模板记录。我的想法是首先创建模板(完成),第二步从文件中取出每条记录,将其输入模板,最后将格式化的记录连接到新文件。Perl是一个经典的unix工具。添加了更多关于如何继续的提示模板部分需要从代码中删除,以使其可用于其他模板。我将使用此工具。
     <%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
#!/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
my @lines = (<>); # just read em all...
my @cleaned = map { chomp } @lines;
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