awk - AWK 合并文件
问题描述
我正在破解一些AWK。我是它的初学者。我已经完成了以下问题的作业,但无法使其正常工作。
原始数据样本:
Start Date 12/3/17
End Date 12/30/17
Report Type Report1
Currency ZAR
Country Identifier MType Quantity Net Net Net Code Title Contrib I_Type M_Type Vendor Identifier Offline Indicator LSN
ZA 44057330 FMP 1 0.050666 0.050666 USYYYYYYYYYY ABC Tom 1 1 USYYYYYYYYYY 0 SUT
ZA 1267456726 SIMT 1 0.03 0.03 USXXXXXXXXXX DEF Frances 1 1 USXXXXXXXXXX 0 XYZ
Row Count 657
Storefront Name MType Quantity Net Net
ZA FMP 601 30.45
ZA IAP 13 0.68
ZA IMP 1035 69.36
ZA SIMP 54 1.4
ZA FMT 70 0.53
ZA IMT 92 1.68
ZA SIMT 6 0.18
期望的输出:
(我在这里没有转义特殊字符。)
"Filename" "Start Date" "End Date" "Currency" "Country" "Identifier" "MType" "Quantity" "Net" "NetNet" "Code" "Title" "Contrib" "I_Type" "M_Type" "Vendor Identifier" "Offline Indicator" "LSN"
"rawfile.txt" "12/3/17" "12/30/17" "ZAR" "ZA" "44057330" "FMP" "1" "0.050666" "0.050666" "USYYYYYYYYYY" "ABC" "Tom" "1" "1" "USYYYYYYYYYY" "0" "SUT"
"rawfile.txt" "12/3/17" "12/30/17" "ZAR" "ZA" "1267456726" "SIMT" "1" "0.03" "0.03" "USXXXXXXXXXX" "DEF" "Frances" "1" "1" "USXXXXXXXXXX" "0" "XYZ"
基本上我只需要从第 5 行获取大部分标题,但我需要的三个字段在第 1-4 行。此外,我不需要以“行数”开头的行和之后的数据。
到目前为止我最好的“猜测”:
gawk '
function basename(file) {
sub(".*/", "", file)
return file
}
/^Row Count/ {nextfile}
FNR == 1 { StartDate=$2; }
FNR == 2 { EndDate=$2; }
FNR == 4 { curr=$2; }
NR == 5 {$0 = "StartDate" OFS "EndDate" OFS "Filename" OFS "curr" OFS $0; print}
FNR > 5 {$0 = StartDate OFS EndDate OFS basename(FILENAME) OFS curr OFS $0; print}
' OFS='\t' path/to/sourcefiles/*.txt > path/to/outfile.txt
谢谢!
编辑:
新表
这些是每个文件中字段标题之前的行。内容从第 4 行开始:
Provider ,,,,,,,,,,,,
01/01/2018 - 01/31/2018,,,,,,,,,,,,
“我的”脚本
它几乎可以工作。但它包含每个文件的第 1-3 行: gawk ' function basename(file) { sub(".*/", "", file) return file } BEGIN { FS=OFS="," } NR < 3 { if ( NR == 2 ) { hdr = "Report_Period" OFS val = val $1 OFS } next } FNR>3 { print "Filename", hdr $0 next } { print basename(FILENAME), val $0 } ' OFS="," /path/to/input/files > ~/path/to/output/file/file.csv
编辑结束
解决方案
您的示例输入格式不清楚,但这可能是您正在寻找的内容,或者它可能做的超出了必要的范围,或者完全是其他事情:
$ cat tst.awk
BEGIN { FS=OFS="\t" }
/^Row Count/ { nextfile }
FNR==1 {
fname = FILENAME
sub(/.*[/]/,"",fname)
}
{
gsub(/[\\]t/,FS)
gsub(/[\\][/]/,"/")
gsub(/[^\t]+/,"\"&\"")
}
FNR < 5 {
if ( FNR != 3 ) {
hdr = hdr $1 OFS
val = val $2 OFS
}
next
}
FNR==5 {
print "\"Filename\"", hdr $0
next
}
{ print "\""fname"\"", val $0 }
$ awk -f tst.awk file
"Filename" "Start Date" "End Date" "Currency" "Country" "Identifier" "MType" "Quantity" "Net" "Net Net" "Code" "Title" "Contrib" "I_Type" "M_Type" "Vendor Identifier" "Offline Indicator" "LSN"
"file" "12/3/17" "12/30/17" "ZAR" "ZA" "44057330" "FMP" "1" "0.050666" "0.050666" "USYYYYYYYYYY" "ABC" "Tom" "1" "1" "USYYYYYYYYYY" "0" "SUT"
"file" "12/3/17" "12/30/17" "ZAR" "ZA" "1267456726" "SIMT" "1" "0.03" "0.03" "USXXXXXXXXXX""DEF" "Frances" "1" "1" "USXXXXXXXXXX" "0" "XYZ"
上面使用 GNU awk 作为你已经在使用的 nextfile。
推荐阅读
- javascript - 如何将数据从子组件(子组件有自己的状态)传递给父组件?
- java - 像素周围的点云(不是点或平面)上的 HitTest-ing
- vba - 添加行,然后用集合中的数据填充这些行
- laravel - 带有 csrf 的 laravel GuzzleHttp 帖子
- oracle - oracle 光标 + FORALL 花费时间
- c# - 从 bin 文件夹而不是 MSTest 中的 ..\Out\... 运行单元测试
- php - 如何使用触发器记录更新更改?
- .net - 在我的 PowerShell FTP 脚本中转义 @ 字符
- selenium - Selenium Webdriver switchTo() 方法在 Chrome 75 中失败
- javascript - 单击输入标签会更改整个内容