我可以将 csv 中的文本作为 csv 文件的名称吗

我可以将 csv 中的文本作为 csv 文件的名称吗

我真的希望我能解释我的问题。非常感谢您的帮助。

我有超过 1000 个 csv 文件,它们看起来一模一样。示例

Malian Aero Company,,,,,Aircraft,TZ-DDG,(Seed 1),,,Block-on (Z),18:19,      Landing (Z),,18:14,Date,06/06/16
2016  MALI  WEATHER  MODIFICATION  PROGRAM,,,,,,,,,,Block-off (Z),16:35,        Takeoff (Z),,16:41,Page,1
,Pilot:,Daniel Chacon,,Co-Pilot:,Malik,,Observer: ,,,Total Time,01:44,    Flight  Time    ,,01:33,Type,Seed
,,,,,,,,,,,,,,,,
Time,Cell,Event,LAT,LON,Alt.,Ejectable (Glacio),,BIP (Hygro),,Remarks,,,,,,
(UTC),No.,No.,(VOR),(DME),(Kft),0,Recycle,Burn,Recycle,,,,,,,
17:03,1,,12.55,-9.03,"8,000",,,1,,,,,,,,
17:06,,,12.67,-9.13,"8,000",,,1,,Updraft 500/900 ft/m,,,,,,
17:11,,,12.56,-9.11,"8,000",,,1,,,,,,,,
17:13,,,12.74,-9.07,"8,000",,,1,,,,,,,,
17:35,2,,13.31,-9.07,"9,000",,,1,,,,,,,,
17:39,,,13.53,-9.05,"9,000",,,1,,,,,,,,

问题是我希望 csv 文件的名称是航班发生的日期,即第 2 行。在此示例中,日期为06/06/16。因此,我希望 csv 文件的名称为20160606。请注意顺序的变化,这可能会使其更加令人困惑。

我怎样才能自动完成此操作?

答案1

此脚本有两个参数。一个用于 csv 文件的目录。另一个用于更正的新文件。

如果您同一天有多个航班,我会将时间添加为文件名的一部分,以确保每个输出文件都有唯一的名称。

剧本:

#!/bin/bash

indir=$HOME/indir
outdir=$HOME/outdir

[[ -d $outdir ]] || (echo "Outdir doesn't exist... Exiting..." ; exit) 

process() {
    file=$1
    datetime=$(head -1 $file|awk -F, '{print $NF"/"$(NF-2)}' | sed s#/#:#g)

    IFS=':' read -r -a arr <<< "$datetime"
    newname=$(printf "20${arr[2]}${arr[0]}${arr[1]}-${arr[3]}${arr[4]}.csv\n")
    echo "Name Change: $file -> $newname"
    sed -e '1,7d' < $file > $outdir/$newname
}

for i in "$indir"/*.csv; do
    process "$i"
done

脚本摘要

脚本的变量和命令:

  • indir:使用变量的脚本因迪尔用于您的 csv 文件的目录。
  • oudir:为要复制的新文件创建此目录。
  • 第一行:在继续执行脚本之前验证输出目录是否存在。
  • arr:用于分割日期并创建新文件名的数组变量。
  • sed:用于删除不需要的行的命令行文本编辑器。

答案2

它可能会让小耶稣(或者至少是拉里·沃尔)哭泣,但是:

prename -n '
  use Text::CSV;
  use Time::Piece;
  open my $fh, "<", $_ or die "$_ : $!";
  eval {
    my $r = Text::CSV->new()->getline($fh);
    s{.*(?=\.csv)}{Time::Piece->strptime($r->[-1], "%d/%m/%y")->strftime("%Y%m%d")}e  if ($r);
    1;
  } 
  or do {
    print "$_ skipped (no valid date field found)\n"
  }
' *.csv
file1.csv renamed as 20160606.csv
file2.csv renamed as 20160623.csv
file3.csv skipped (no valid date field found)
file.csv : Permission denied at (eval 8) line 4.

笔记:

  1. 它假定日期位于每个文件第一行的最后一列
  2. 它假设原始日期格式是,"%d/%m/%y"但你给出的例子可以理解为"%m/%d/%y"- 你需要检查并在必要时进行调整

它应该跳过无法在预期位置解析有效日期的文件:日期解析的错误处理取自Perl 中的异常处理:如何处理外部模块中的致命错误

去除 -n 仅当/当你确信它在做正确的事情时。

答案3

您可以使用cut选择您需要的精确列,然后可以使用date例如,与 sed 结合使用)来设置文件名。

将其放入循环中以遍历所有文件,就完成了。

为了帮助您:

cut --delim="," -f17 yourfile.csv | head -n1

这将选择日期,现在轮到您转换它了。

相关内容