如何根据每行上找到的值将文件带有sed拆分为多个文件?

问题描述

我有几个Company_***.csv files(尽管分隔符是一个制表符,而不是逗号;因此应该是* .tsv,但不要紧),其中包含一个标题和许多数据行,例如

1stHeader   2ndHeader   DateHeader  OtherHeaders...
111111111   SOME STRING 2020-08-01  OTHER STRINGS..
222222222   ANOT STRING 2020-08-02  OTHER STRINGS..

我必须根据这里的第三列进行拆分,这是一个日期。

每个文件的名称应类似于Company_2020_08_01.csv Company_2020_08_02.csv等 并包含:第一行的标头+匹配以下行的行。

起初我考虑过将标头保存(一次)到一个文件中,例如

 sed -n '1w Company_header.csv' Company_*.csv

然后使用日期格式解析文件(因此,标题将被跳过),例如

sed -n '/\t2020-[01][0-9]-[0-3][0-9]\t/w somefilename.csv' Company_*.csv

...,最后,在每个生成的文件中插入(丢失)标头。

但是我陷入了第2步:找不到w命令期望的“动态生成”(filename)“文件名”的方法,也找不到如何捕获搜索模式中的日期(因为显然这只是一个地址,而不是s/regexp/replacement/[flags]命令中的搜索替换“字段”,因此您不能拥有捕获组{{1 }}。

所以我想知道( )是否真的可行?或者我应该看看其他工具,例如sed

免责声明:我对这些命令相当满意,所以我只是从头开始学习/开始...

解决方法

抢救Perl!

perl -e 'while (<>) {
    $h = $_,next if $. == 1;
    $. = 0 if eof;
    @c = split /\t/;
    open my $out,">>","Company_" . $c[2] =~ tr/-/_/r . ".csv" or die $!;
    print {$out} $h unless tell $out;
    print {$out} $_;
}' -- Company_*.csv
  • 标量上下文中的菱形运算符<>从输入中读取一行。
  • 每个文件的第一行存储在变量$h中,请参见$.eof
  • split用每一行的列值填充@c数组
  • $c[2]包含日期,我们使用tr将破折号转换为下划线以从中创建文件名。 open打开文件进行添加。
  • print如果文件为空,则显示标题(请参见tell
  • 并打印当前行。

请注意,它只会附加到文件中,因此请不要忘记在再次运行脚本之前删除任何输出文件。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...