【问题标题】:Split file by date and keep header in Bash按日期拆分文件并在 Bash 中保留标题
【发布时间】:2015-10-21 00:32:54
【问题描述】:

我需要使用 OS X 10.10 附带的任何标准 CLI 工具按日期拆分 TSV 文件;例如sed、awk 等。仅供参考,shell 是 Bash

输入文件有一个标题行并遵循制表符分隔格式(日期和时间在第一列中)- 我在下面添加“\t”以显示选项卡,并添加“...”以指示行还有更多列:

Transaction Date\t Account Number\t…
9/16/2004 12:00:00 AM\t ABC00147223\t…
9/17/2004 12:00:00 AM\t ABC00147223\t…
10/05/2004 12:00:00 AM\t ABC00147223\t…

输出应该是:

  1. 每个唯一的年和月都有一个单独的文件(根据上面的示例,我会得到 2 个输出文件:9/2004 和 10/2004)
  2. 维护原始文件的第一行/标题行
  3. YYYYMM.txt 格式的文件名

感谢您的帮助。

【问题讨论】:

  • Awk 是完成这项工作的正确工具 - 进行一些研究,尝试自己使用它,然后 edit 提出问题,以表明如果您有任何问题,您会遇到什么困难。跨度>
  • 您的输出文件是否应该只包含 1 行,并且所有输出文件的 Transaction Date\t Account Number\t.. 是否相同?

标签: bash split


【解决方案1】:

如果您想在 bash shell 中执行纯操作,请执行以下操作...

#!/bin/bash

datafile=inputdatafile.dat
ctr=0;

while read line
do

  # counter to keep track of line number
  ctr=$((ctr + 1))

  # skip header line for processing
  if [[ $ctr -gt 1  ]];
  then
      # create filename using date field present in record
      vdate=${line%% *}               
      vday1=${vdate%%/*}              
      vday=`printf "%02d" $vday1`     # day with padding 0
      vyear=${vdate##*/}              # year
      vfilename="${vyear}${vday}.txt" # filname in YYYYMM.txt format

      # check if file exists or not then put header record in it
      if [ ! -f $vfilename ]; then
        head -1 $datafile > $vfilename
      fi

      # put the record in that file
      echo "$line" >> $vfilename
  fi

done < $datafile

不确定您的数据文件有多大,但使用 shell 脚本解析大文件绝不是一个好主意,而是使用 awk、sed、grep 等其他实用工具。

对于大文件并使用 nawk / gawk 单线使用如下...它将满足您的所有需求。

# use nawk or gawk if you don't get the expected results using awk
$nawk '{if(NR==1)h=$0;} {if(NR>1){ split($1,a,"/"); fn=sprintf("%04d%02d.txt",a[3],a[1]); if(system( "[ ! -f  " fn " ] ")==0)print h >> fn; print >> fn;} }' inputdatafile.dat 

【讨论】:

  • 谢谢@narendra!这样可行!! — 我还编辑了我的问题,以更清楚地表明我很高兴(实际上更喜欢)使用标准工具。我只是想说 shell 是 Bash——并不是我特别想要一个 bash 脚本。问题:我可以说您回答了我的问题而没有关闭它,以便我可以使用 awk、sed 等获得其他建议(因为我需要处理大文件)。谢谢!
  • 我修改了我的答案,也使用 awk 提供了相同的答案。
  • 你真是太棒了!我使用了你第二个建议的 awk 版本,它也很有魅力!
  • 实际上——我被迷住了。然后当我对结果文件进行分类时,我发现使用 awk 它在 750 行文件的第 41 行之后停止了……我也不知道为什么……最后一行以:10/10/2007 12:00:00 AM 和下一行是:11/9/2007 12:00:00 AM。在 OSX 上,我没有 nawk 或 gawk……
  • 我看不出 awk 代码有任何理由让它在第 41 行停止,除非数据文件出现问题...尝试使用不同的文件,看看您的问题是否仍然存在以及是否有任何共同点错误行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-24
  • 2016-09-20
  • 1970-01-01
  • 2020-06-22
  • 1970-01-01
  • 2020-07-13
  • 1970-01-01
相关资源
最近更新 更多