我有一个输入文件,我需要转换为DB友好。
原件:
H|cust_id|order_no
D|itemcode|itemdesc
D|itemcode|itemdesc
期望的输出:
itemcode|itemdesc|cust_id|order_no
itemcode|itemdesc|cust_id|order_no
我正在阅读sed
,但无法理解。
答案 0 :(得分:3)
awk
比sed
awk -F'|' '$1=="H" { c=$2; o=$3 } $1=="D" { printf("%s|%s%|%s|%s\n", $2, $3, c, o) }'
如果必须在sed
中完成,则保留空间是关键。在文件script.sed
中:
sed -e '/^H|/{ s/^H|//; h; d; }' \
-e '/^D|/{ s/^D|//; G; s/\n/|/; }'
第一行与H
行匹配,删除H|
,并保存保留空间中剩余的内容,并删除该行以防止打印任何内容。
第二行匹配D
行,删除D|
,将换行符和保留空间的内容附加到模式空间,用管道替换换行符,并打印结果
给定输入文件data
:
H|cust_id-1|order_no-11
D|itemcode-1|itemdesc-1
D|itemcode-2|itemdesc-2
H|cust_id-2|order_no-22
D|itemcode-3|itemdesc-3
D|itemcode-4|itemdesc-4
示例输出:
$ awk -F '|' '$1 == "H" { c=$2; o=$3 } $1 == "D" { printf("%s|%s%|%s|%s\n", $2, $3, c, o) }' data
itemcode-1|itemdesc-1|cust_id-1|order_no-11
itemcode-2|itemdesc-2|cust_id-1|order_no-11
itemcode-3|itemdesc-3|cust_id-2|order_no-22
itemcode-4|itemdesc-4|cust_id-2|order_no-22
$ sed -e '/^H|/{ s/^H|//; h; d; }' -e '/^D|/{ s/^D|//; G; s/\n/|/; }' data
itemcode-1|itemdesc-1|cust_id-1|order_no-11
itemcode-2|itemdesc-2|cust_id-1|order_no-11
itemcode-3|itemdesc-3|cust_id-2|order_no-22
itemcode-4|itemdesc-4|cust_id-2|order_no-22
$
答案 1 :(得分:0)
使用两个 sed
命令(假设输入文件file
),这是一个可能更容易理解的解决方案:
# Extract header values from the 1st line, dropping the 1st column.
headerValues=$(sed -E '1 s/[^|]*\|//; q' file)
# Append header values to all subsequent lines, dropping the 1st column.
sed -En '2,$ s/[^|]*\|(.*)/\1|'"$headerValues"'/p' file
# Additional requirement, added later by the OP:
# Store the first header value separately in shell variable $firstHeaderValue.
IFS='|' read -r firstHeaderValue rest <<<"$headerValues"
注意:
sed
命令应该适用于Linux和OSX / FreeBSD。