我真的希望我能解释我的问题。非常感谢您的帮助。
我有超过 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.
笔记:
- 它假定日期位于每个文件第一行的最后一列
- 它假设原始日期格式是,
"%d/%m/%y"
但你给出的例子可以理解为"%m/%d/%y"
- 你需要检查并在必要时进行调整
它应该跳过无法在预期位置解析有效日期的文件:日期解析的错误处理取自Perl 中的异常处理:如何处理外部模块中的致命错误。
去除 -n
仅当/当你确信它在做正确的事情时。
答案3
您可以使用cut
选择您需要的精确列,然后可以使用date
(例如,与 sed 结合使用)来设置文件名。
将其放入循环中以遍历所有文件,就完成了。
为了帮助您:
cut --delim="," -f17 yourfile.csv | head -n1
这将选择日期,现在轮到您转换它了。