3

我有一个 CSV 文件,其中包含如下数据:-

1,275,,,275,17.3,0,"2011-05-09 20:21:45"
2,279,,,279,17.3,0,"2011-05-10 20:21:52"
3,276,,,276,17.3,0,"2011-05-11 20:21:58"
4,272,,,272,17.3,0,"2011-05-12 20:22:04"
5,272,,,272,17.3,0,"2011-05-13 20:22:10"
6,278,,,278,17.3,0,"2011-05-13 20:24:08"
7,270,,,270,17.3,0,"2011-05-13 20:24:14"
8,269,,,269,17.3,0,"2011-05-14 20:24:20"
9,278,,,278,17.3,0,"2011-05-14 20:24:26"

该文件包含 4432986 行数据。

我希望根据最后一列中的日期将新文件名拆分出来。

因此,根据上面的数据,我想要 6 个新文件,每个文件中每天都有行。

我想要以 YYYY_MM_DD 格式命名的文件。

我也想忽略输出数据中的第一列

因此文件 2011_05_13 将包含以下行,第一列除外:-

272,,,272,17.3,0,"2011-05-13 20:22:10"
278,,,278,17.3,0,"2011-05-13 20:24:08"
270,,,270,17.3,0,"2011-05-13 20:24:14"

我打算在 linux 机器上执行此操作,所以使用任何 linux 实用程序的任何东西都会很酷,sed awk 等?

4

6 回答 6

6

这是一个适合您的单行代码awk

awk -F "," '{ split ($8,array," "); sub ("\"","",array[1]); sub (NR,"",$0); sub (",","",$0); print $0 > array[1] }' file.txt

实现了所需的输出,尽管也许其中一些代码可以更简洁。HTH。

编辑:

从左到右阅读代码:

  • -F ","
    是的,这设置了分隔符。

  • split ($8,array," ")
    这会拆分空间上的第八列,并将此信息放入一个名为 的数组中array

  • sub ("\"","",array[1])
    我们取第一个数组元素(这是一个将成为我们的输出文件名的切片)并替换掉前导"符号(我们需要对"符号进行转义,因此我们将\字符放在前面)。

  • sub (NR,"",$0)
    这可以方便地从文件开头删除行号(NR是行号$0,当然是分隔之前的整行输入)。

  • sub (",","",$0)
    这将删除行号后的逗号。

  • 现在我们有了一个干净的文件名和一行干净的数据,我们可以$0写入array[1]: print $0 > array[1]

使固定:

因此,如果您更喜欢下划线而不是hypon,我们需要解决的只是array[1]. 我刚刚添加了一个全局替换:gsub ("-","_",array[1]).

更新后的代码是:

awk -F "," '{ split ($8,array," "); sub ("\"","",array[1]); gsub ("-","_",array[1]); sub (NR,"",$0); sub (",","",$0); print $0 > array[1] }' file.txt

HTH。

于 2012-04-18T22:07:06.127 回答
2

你可以使用这个 awk 命令:

awk -F, 'BEGIN{OFS=",";} {dt=$8; gsub(/^"| .*"$/,"", dt);
$1=""; sub(/^,/, "", $0); print $0 > dt}' input.txt
于 2012-04-18T22:11:51.900 回答
1

脚本语言(perl/python)可能是您最好的选择,但我喜欢在 bash 中执行此操作的挑战,所以就在这里。

 cat bigfile.txt | while read LINE;
  do echo $LINE >> `echo $LINE | cut -d, -f8 | cut -c2-11`.txt ;
 done

基本上,它的作用是在循环中逐行读取文件while,然后根据日期将该行附加到文件中。

cut使用两个命令的组合提取日期。第一个cut使用逗号分隔符 ( ) 拉出最后一列(第 8 列-d,),然后第二个cut通过删除第一列仅拉出日期",然后直到字符 11。


现在,要解决删除第一列的问题:

cat bigfile.txt | sed 's/^.*?,//'

这个正则表达式只是删除第一个逗号之前的所有内容。

因此,我们将用这个替换 while 循环的开头,留下:

 cat bigfile.txt | sed 's/^.*?,//' | while read LINE;
  do echo $LINE >> `echo $LINE | cut -d, -f8 | cut -c2-11`.txt ;
 done
于 2012-04-18T20:57:51.640 回答
1

这个怪物会抓取所有唯一的日期,然后用 greps 查找原始文件中的这些键,并将它们保存到由该键命名的文件中。是的,猫没用,但试图原子化动作。

cat records.txt \
| cut -f8 -d, \
| cut -f1 -d ' ' \
| tr -d '"' \
| sort -u \
| while read DATE ; do \
    cat records.txt \
    | cut -f2- -d, \
    | egrep ",\"${DATE} [0-9]{2}:[0-9]{2}:[0-9]{2}\"" \
    > ${DATE}.txt
done
于 2012-04-18T20:58:35.853 回答
0

一定很简单

$ sed 's/^[0-9]*,//' your_gigantic_data.csv
于 2012-04-18T21:12:00.200 回答
0

这可能对您有用:

sed 's/^[^,]*,\(.*"\(....\)-\(..\)-\(..\).*\)/echo \1 >>\2_\3_\4.csv/' file | sh

或 GNU sed:

sed 's/^[^,]*,\(.*"\(....\)-\(..\)-\(..\).*\)/echo \1 >>\2_\3_\4.csv/e' file
于 2012-04-18T22:36:05.467 回答