【问题标题】:AWK to Consolidate FilesAWK 合并文件
【发布时间】:2018-12-11 03:54:15
【问题描述】:

我正在破解一些 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 行: 傻瓜' 功能基本名称(文件){ 子(“.*/”,“”,文件) 返回文件 } 开始 { FS=OFS="," } NR 3 { 打印“文件名”,hdr $0 下一个 } { 打印基本名称(文件名),价值 $0 } ' OFS="," /path/to/input/files > ~/path/to/output/file/file.csv

编辑结束

【问题讨论】:

  • “原始数据示例”中的那些\ts 真的存在还是应该代表制表符?日期中的每个正斜杠之前是否有真的反斜杠?请确保您发布的示例输入正是您要解析的输入格式。

标签: awk


【解决方案1】:

您的示例输入格式不清楚,但这可能是您正在寻找的内容,或者它可能做的超出了必要的范围或完全是其他事情:

$ 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,你已经在使用它了。

【讨论】:

  • 谢谢埃德。那行得通。您对示例数据是正确的——我只是想让某人更容易使用转义的特殊字符进行剪切粘贴。无论如何,对于这篇文章的任何未来读者,我都按照您的建议返回并更改了它。 (现在我必须回去尝试弄清楚它是如何工作的以及为什么起作用,所以我可以从中学习。)
  • Ed:gsub 部分,如果你愿意的话,只是因为我的示例中有转义字符,对吗?
  • 它将\t 字符串转换为制表符并将\/ 字符串转换为/ 字符,所以对于那些是肯定的,然后它将每个字段都用双引号括起来,无论前 2 步。
  • 完美;谢谢。我就是这么想的。实际的原始数据没有那些转义,所以我会相应地编辑正则表达式。这就是我们学习的方式! :)
  • 完成。我希望我做得“正确”。我真的不懂礼节;我只是做出我最好的猜测。 stackoverflow.com/questions/51181188/…
猜你喜欢
  • 2018-12-13
  • 1970-01-01
  • 2014-07-02
  • 2016-06-28
  • 2013-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多