我需要将输入文件转换为更标准化的内容,以便将sql加载器插入到Oracle 8i数据库中(是的,我们与时俱进!)。问题是文件被格式化为垂直列出每个线元素所以我需要以某种方式循环它并建立一个有效的行,因为我进行创建所需的输出文件进行加载。
我知道它应该是相对可以实现的,但我对AWK / SED的所有事情都是全新的,虽然我通过浏览网站(例如这个)和一些网站取得了一些进展我买的书,时间限制意味着我需要一些更专业的建议来帮助我。
我相信我可以通过构建一个或多个数组然后使用while循环遍历其余数据来做我需要的东西,但是虽然我可以构建数组没关系,但我并不完全确定我是怎么做的可以将它们连接在一起,或者即使我正在做的是最好的方法。
无论如何......从我这里来的莫名其妙。
这是我需要处理的数据文件的一小部分。它基本上是对从供应商发送给我们的书籍的确认:
UNB+UNOA:2+5060096369998:14+[BUYER GLN]:14+150310:0105+000023++DESADV'
UNH+0000001+DESADV:D:96A:UN:EAN005'
BGM+351+[INVOICE NUMBER]'
DTM+137:20150309:102'
DTM+11:20150309:102'
DTM+63:20150310:102'
NAD+BY+[BUYER GLN]::9++[BUYER NAME AND ADDRESS]'
NAD+SU+5060096369998::9++GARDNERS BOOKS LTD.+1 WHITTLE DRIVE:WILLINGDON DROVE:EASTBOURNE+++BN23 6QH+GB'
NAD+DP+[SHIPPING GLN]::9++[SHIPPING NAME AND ADDRESS]'
CPS+1'
PAC+3++PK'
MEA+PD+AAB+KGM:11'
MEA+PD+HT+MMT:460'
MEA+PD+WD+MMT:310'
MEA+PD+LN+MMT:235'
PCI+33E'
GIN+BJ+305060096368359186'
LIN+1++9780006755227:EN'
PIA+1+0006755224:IB'
IMD+F+BST+:::DOGSBODY/JONES, DIANA WYNNE'
QTY+12:1'
RFF+ON:124705572-15-1'
LIN+2++9780007245826:EN'
PIA+1+0007245823:IB'
IMD+F+BST+:::VINTAGE AFFAIR/WOLFF, ISABEL'
QTY+12:3'
RFF+ON:124705572-62-1'
LIN+3++9780007250608:EN'
PIA+1+0007250606:IB'
IMD+F+BST+:::MYSTERY OF THE BLUE TRAIN COMIC STR'
QTY+12:1'
RFF+ON:124705572-48-1'
PAC+3++PK'
MEA+PD+AAB+KGM:11'
MEA+PD+HT+MMT:460'
MEA+PD+WD+MMT:310'
MEA+PD+LN+MMT:235'
PCI+33E'
GIN+BJ+305060096368359193'
LIN+4++9780091950309:EN'
PIA+1+0091950309:IB'IMD+F+BST+:::LOVER/JORDAN, NICOLE'
QTY+12:1'
RFF+ON:124705572-98-1'
LIN+5++9780099453956:EN'
PIA+1+0099453959:IB'IMD+F+BST+:::FLANDERS PANEL/PEREZ-REVERTE, ARTUR'
QTY+12:1'
RFF+ON:124705572-22-1'
LIN+6++9780099481379:EN'
PIA+1+0099481375:IB'
IMD+F+BST+:::MYSTERIOUS FLAME OF QUEEN LOANA/ECO'
QTY+12:2'
RFF+ON:124705572-36-1'
CNT+1:9'
CNT+2:6'
UNT+695+0000001'
UNZ+1+000023'
忽略前几行,我真正感兴趣的行是开始GIN的行(这些是单独的记录标识符),LIN(包含书籍ISBN),QTY(包含数量有趣的数量)和RFF (包含我们的内部参考)。
将字段分隔符设置为[+:] +我需要从每个GIN记录开始并从该行检索$ 3(这是我最初添加到我的数组中的内容)。虽然该值保持不变,但我想继续浏览文件,对于每个LIN记录,我想从LIN,QTY和RFF字段中获取$ 3值,并在同一行上打印出来,包括GIN值。一旦GIN记录改变,我们继续如上所述,但现在我们在每行的字段1中打印出新的GIN值。输出上的字段分隔符可以是空格或逗号(或其他任何东西),理想情况下我想摆脱撇号'也出现在每个值/行的末尾。
输出结果如下所示(我实际上包含了行标识符($ 1),以便更容易理解,但最终打印并不真正需要它们):
GIN305060096368359186,LIN9780006755227,QTY1,RFF124705572-15-1
GIN305060096368359186,LIN9780007245826,QTY3,RFF124705572-62-1
GIN305060096368359186,LIN9780007250608,QTY1,RFF124705572-48-1
GIN305060096368359193,LIN9780091950309,QTY1,RFF124705572-98-1
GIN305060096368359193,LIN9780099453956,QTY1,RFF124705572-22-1
GIN305060096368359193,LIN9780099481379,QTY2,RFF124705572-36-1
我没有添加任何我的尝试,因为它们很多,而且可能都是垃圾。完整文件最终会有30或40个GIN记录,每个记录大约有30条LIN记录。
非常感谢任何帮助。
谢谢, 菲尔
答案 0 :(得分:0)
以下是如何实现这一目标:
首先,你需要知道它是什么类型的行:
is_gin=`echo $i | grep "GIN+"`
is_lin=`echo $i | grep "LIN+"`
is_qty=`echo $i | grep "QTY+"`
is_rff=`echo $i | grep "RFF+"`
然后您需要针对以下各项进行特定处理:
只需拿这个数字
gin=`echo $i | grep -o '[0-9]*'`
删除++之前的所有内容,并在
之后仅取数字linreq=`echo $i | sed 's/.*++//g' | grep -o '[0-9]*'`
取全部数字后:删除:
之后qty=`echo $i | grep -o ':[0-9]*' | sed -e 's/://g'`
仅采用模式XXXXX-XXXX-XXXX(与X一样多)
rff=`echo $i | grep -o '[0-9]*-[0-9]*-[0-9]*'`
然后这只是一些处理循环并检查新行。这是您的脚本:processing.sh input_file output_file
#!/bin/bash
IFS=$'\n' #line delimiter
#empty your output file
cp /dev/null "$2"
for i in $(cat "$1"); do
is_gin=`echo $i | grep "GIN+"`
is_lin=`echo $i | grep "LIN+"`
is_qty=`echo $i | grep "QTY+"`
is_rff=`echo $i | grep "RFF+"`
if [ ! -z "$is_gin" ]; then
#gin=`echo $i | grep -o '[0-9]*'`
gin=`echo $i | awk 'match($0,/[0-9]{1,}/) {print substr($0,RSTART,RLENGTH)}'`
newline=0
linecontent="GIN${gin},"
elif [ ! -z "$is_lin" ]; then
#linreq=`echo $i | sed 's/.*++//g' | grep -o '[0-9]*'`
linreq=`echo $i | sed 's/.*++//g' | awk 'match($0,/[0-9]{1,}/) {print substr($0,RSTART,RLENGTH)}'`
if [ -z "$linecontent" ]; then
linecontent="GIN${gin},LIN${linreq},"
else
linecontent="${linecontent}LIN${linreq},"
fi
elif [ ! -z "$is_qty" ]; then
#qty=`echo $i | grep -o ':[0-9]*' | sed -e 's/://g'`
qty=`echo $i | awk 'match($0,/:[0-9]{1,}/) {print substr($0,RSTART,RLENGTH)}' | sed -e 's/://g'`
linecontent="${linecontent}QTY${qty},"
elif [ ! -z "$is_rff" ]; then
#rff=`echo $i | grep -o '[0-9]*-[0-9]*-[0-9]*'`
rff=`echo $i | awk 'match($0,/[0-9]{1,}-[0-9]{1,}-[0-9]{1,}/) {print substr($0,RSTART,RLENGTH)}'`
linecontent="${linecontent}RFF${rff}"
echo $linecontent >> "$2"
linecontent=""
fi
done
cat $2
输出:
GIN305060096368359186,LIN9780006755227,QTY1,RFF124705572-15-1
GIN305060096368359186,LIN9780007245826,QTY3,RFF124705572-62-1
GIN305060096368359186,LIN9780007250608,QTY1,RFF124705572-48-1
GIN305060096368359193,LIN9780091950309,QTY1,RFF124705572-98-1
GIN305060096368359193,LIN9780099453956,QTY1,RFF124705572-22-1
GIN305060096368359193,LIN9780099481379,QTY2,RFF124705572-36-1
我添加了awk符号,可以满足您的需求