目前,我们的地址流会导致邮件文件错误和物理文件错误,并且我们无法在作业中重命名文件。
文件名:
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.txt
(physicalfiles.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 的文件通配特征。如果您启用extglob
shell 选项,并且时间戳的分钟元素的文件格式始终为两位数,那么适合您的情况的文件 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.txt
和mailing_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