如何唯一标识文件名?

如何唯一标识文件名?

目前,我们的地址流会导致邮件文件错误和物理文件错误,并且我们无法在作业中重命名文件。

文件名:

s_4800_agency_addresses_1_10_2018_14_13_standard_error.csv - Mailing file
s_4800_agency_addresses_1_10_2018_14_13_1_standard_error.csv - Physical file

这就是我的要求。我有上面提到的两个文件。我需要将这些文件的名称放置在两个不同的文件中。将WITHOUT _1 文件放入一个文件,将WITH _1 文件放入另一文件。

答案1

您可以迭代与第一种文件类型匹配的模式,并通过修改每个名称来挑选第二种类型的文件:

#!/bin/sh

rm -f mailfiles.txt
rm -f physicalfiles.txt

for mailfile in s_4800_agency_addresses_*_standard_error.csv; do
    prefix=${mailfile%_standard_error.csv}
    physicalfile="${prefix}_1_standard_error.csv"

    if [ -f "$physicalfile" ]; then
         printf '%s\n' "$mailfile"     >>mailfiles.txt
         printf '%s\n' "$physicalfile" >>physicalfiles.txt
    fi
done

在上述循环的每次迭代中,$mailfile将是当前目录中与模式匹配的文件名s_4800_agency_addresses_*_standard_error.csv,例如您提到的两个文件名中的任何一个。

由此,我们挑选出前缀,即除了结尾之外的所有内容_standard_error.csv,然后通过添加该前缀来构造一个新的文件名_1_standard_error.csv。如果结果名称对应于现有文件,那么我们知道这$mailfile就是您所说的“邮件文件”,并且这$physicalfile是相应的“物理文件”,我们将这两个名称分别打印到 和 中mailfiles.txtphysicalfiles.txt这些结果文件最初被删除) 。

如果没有与新构建的文件名相对应的文件,那么我们就击中了“物理文件”之一(或没有相应“物理文件”的“邮件文件”),并且它被忽略。

运行这个:

$ ls -1
s_4800_agency_addresses_1_10_2018_14_13_1_standard_error.csv
s_4800_agency_addresses_1_10_2018_14_13_standard_error.csv

(这里运行脚本)

$ ls -1
mailfiles.txt
physicalfiles.txt
s_4800_agency_addresses_1_10_2018_14_13_1_standard_error.csv
s_4800_agency_addresses_1_10_2018_14_13_standard_error.csv

$ cat mailfiles.txt
s_4800_agency_addresses_1_10_2018_14_13_standard_error.csv

$ cat physicalfiles.txt
s_4800_agency_addresses_1_10_2018_14_13_1_standard_error.csv

(为了可读性添加了空行)

答案2

编辑:这个问题与原来的问题相比发生了很大变化。此时,您的要求似乎是收集文件名对以插入到两个输出文件中。

为此,您需要使用 shell 的文件通配特征。如果您启用extglobshell 选项,并且时间戳的分钟元素的文件格式始终为两位数,那么适合您的情况的文件 glob 解决方案并不困难。在这种情况下,请尝试:

for physical in *_addresses_+([0-9_])_1_standard_error.csv ; do
  mailing=${physical/_1_s/_s}
  # Do your own thing, but for testing ...
  printf "Pair:\n  %s\n  %s\n" "$mailing" "$physical"
  done

现在,对于您的要求的下一部分,您似乎希望将每对文件的名称放入第三个和第四个输出文件中。为此printf,如果您只想要一个简单的输出列表,或者sed需要更复杂的插入,则可以使用它。

对于第一种(简单)情况:

for physical in *_addresses_+([0-9_])_1_standard_error.csv ; do
  mailing=${physical/_1_s/_s}
  printf "%s\n" "$mailing"  >> path/to/your_mailing_list.txt
  printf "%s\n" "$physical" >> path/to/your_physical_list.txt
  done

对于第二种更复杂的情况,为每个输出模板文件准备两个保证唯一的字符串,一个 for$physical和一个 for $mailing,然后使用sed将这些字符串替换为文件名。在下面,我选择的唯一字符串是@physical@mailing,模板文件称为physical_template.txtmailing_template.txt,最终输出将是以下形式的唯一名称文件result_{$physical or $mailing}.txt:

for physical in *_addresses_+([0-9_])_1_standard_error.csv ; do
  mailing=${physical/_1_s/_s}
  sed "s/@physical/$physical/g" physical_template.txt > result_$physical.txt
  sed "s/@mailing/$mailing/g" mailing_template.txt > result_$mailing.txt
  done

相关内容