用于查找并组合与复杂名称模式匹配的文件的命令

用于查找并组合与复杂名称模式匹配的文件的命令

我的 Linux 目录包含文件转储,它们看起来像:

EDW_Infile_ABC_Daily_Activity_20190204.csv
EDW_Infile_ABC_Daily_Activity.zip
EDW_Infile_PQRInc_Daily_Activity_20190204.csv
EDW_Infile_PQRInc_Daily_Activity_zip
EDW_Infile_ABC_Daily_Payment_20190204.csv
EDW_Infile_PQRInc_Daily_Payment_20190204.csv
EDW_Infile_ABC_Daily_Status_20190204.csv
EDW_Infile_PQRInc_Daily_Status_20190204.csv

这些文件遵循一些常见的名称模式,例如

EDW_Infile_*<3 to 8 bytes company name>*_Daily_Activity_*YYYYMMDD*.csv
EDW_Infile_*<3 to 8 bytes company name>*_Daily_Payment_*YYYYMMDD*.csv
EDW_Infile_*<3 to 8 bytes company name>*_Daily_Status_*YYYYMMDD*.csv

我怎么能够 -

1) 查找所有客户、所有日期的所有文件,其遵循模式 EDW_Infile_{3 到 8 字节任意名称}_每日_活动_{任何日期}.csv

2) 每个文件都包含一个标头。如何将它们全部合并到一个文件中并且只有一个标头

答案1

我稍微介绍了我的 zsh 知识,以便更具体地回答,以防您无法控制文件名并且文件名为类似EDQ_Infile_some uninteresting stuff here_Daily_Activity_junk here.csv,因此不想使用*通配符。

要收集文件名列表...

遵循模式 EDW_Infile_{3 到 8 字节任意名称}_Daily_Activity_{任意日期}.csv

我会在 zsh 中设置这个 Extended_glob 模式(不要输入$-- 这是 shell 提示符):

$ set -o extended_glob
$ files=(EDW_Infile_?(#c3,8)_Daily_Activity_[[:digit:]](#c8).csv)

除了纯文本之外,该模式是:

  • ?-- 任何(单个)字符
  • (#c3,8)-- 需要三到八个字符(含)
  • [[:digit:]]-- 需要一个数字
  • (#c8)-- 需要八个

查看列表:

$ print -l $files
EDW_Infile_ABC_Daily_Activity_20190204.csv
EDW_Infile_PQRInc_Daily_Activity_20190204.csv

到那时...

将它们全部合并到一个文件中,并且只有一个标头

{ head -1 "${files[1]}"; for f in $files; do sed 1d "$f"; done; } > output.csv

这会将两个命令分组并将其输出重定向到output.csv.第一个命令head,从数组中的第一个文件中获取第一行;然后第二个命令循环遍历所有文件并删除第一行(默认将剩余部分打印到标准输出)。

答案2

你可能想要这样的东西

# collect all the "EDW_Infile_ABC" prefixes
declare -A prefix
for f in EDQ_Infile_*_Daily_Activity_*.csv; do
    p=${f%_*.csv}
    prefix[$p]=1
done

for p in "${!prefixes[@]}"; do
    awk 'NR==1 {print} FNR==1{next} {print}' "$p"_*.csv > "$p"_all.csv
    zip "$p".zip "$p"_all.csv
    rm  "$p"_all.csv
done

对于 bash,关联数组需要版本 4。否则,我们可以使用位置参数。

相关内容