我是Shell Script的新手,我要求使用Shell脚本从目录中选择最新文件
目录名称:FTPDIR
文件在这个目录中将是
APC5502015VP072020121826.csv
APC5502015VP082020122314.csv
APC5502015VP092020121451.csv
CBC5502015VP092020122045.csv
CBC5502015VP102020122045.csv
S5502015VP072020121620.csv
S5502015VP072020122314.csv
S5502015VP092020122045.csv
注意:(需要从每个组中选择一个最新版本) - 以下是我在执行shell脚本后需要获得的输出
APC5502015VP092020121451.csv
CBC5502015VP102020122045.csv
S5502015VP092020122045.csv
例如:在最新的文件APC5502015VP092020121451.csv
中,no 092020121451是日期部分,格式为:MMDDYYYYHHMM
,字符串部分为APC5502015VP(字符串部分未固定长度)
我需要使用shell脚本
从dir中选择这三个文件你能帮我解决这个问题吗?
答案 0 :(得分:2)
在bash中安全地执行此操作确实存在问题。正如Jonathan所提到的,像空格或换行符这样的“特殊”字符可能会打乱你的剧本。
如果我们可以假设不存在任何这些,那么我们可以在bash中完成大部分工作,而不涉及其他工具。
# Make an associative array to record types, in the second loop...
declare -A a
for file in *.csv; do
# First, we convert the filenames into something that can be sorted.
# The next three lines account for your "unknown length" in the first part
# of the filename. We assume the date+time is the 12 chars before ".csv".
new="$(rev <<<"$file")"
new="${new:4:12}"
new="$(rev <<<"$new")"
new="${new:4:4}${new:0:2}${new:2:2}${new:8:4}"
len=$(( ${#file} - 16 ))
echo "$new ${file:0:$len} $file"
done | sort | while read date type file; do
# Next, we print only the first of each "type"...
if [[ ${a[$type]} -eq 0 ]]; then
a[$type]=1
echo "$file"
fi
# And stop once we have collected three types.
if [[ ${#a[*]} -ge 3 ]]; then
break
fi
done
正如我所说,这不会处理文件名中的换行符。
另请注意,这会使用{b}内置的rev
和sort
。 rev
部分可以在内部完成,使用更多代码,可能使它们执行得更快,但在极端情况下你只能看到差异。关于sort
我们无能为力,因为bash中没有内置。
答案 1 :(得分:1)
此Perl脚本适用于给定的数据。毫无疑问,它可以得到改善。
#!/usr/bin/env perl
use strict;
use warnings;
my %bases;
while (<>)
{
chomp;
my $name = $_;
my($prefix, $mmdd, $yyyy, $hhmm) = ($name =~ m/(.*)(\d{4})(\d{4})(\d{4})\.csv/);
#print "$name = $prefix $yyyy $mmdd $hhmm\n";
my $stamp = "$yyyy$mmdd$hhmm";
if (!exists($bases{$prefix}) || ($stamp > $bases{$prefix}->{stamp}))
{
$bases{$prefix} = { name => $name, stamp => $stamp };
}
}
foreach my $prefix (sort keys %bases)
{
print "$bases{$prefix}->{name}\n";
}
输出:
APC5502015VP092020121451.csv
CBC5502015VP102020122045.csv
S5502015VP092020122045.csv
答案 2 :(得分:0)
这是awk解决方案:
cd FTPDIR
ls -1|awk -F"VP" '{split($2,a,".");if(a[1]>b[$1]){b[$1]=$2}}END{for(i in b)print i"VP"b[i]}'
下面测试:
> cat temp
APC5502015VP072020121826.csv
APC5502015VP082020122314.csv
APC5502015VP092020121451.csv
CBC5502015VP092020122045.csv
CBC5502015VP102020122045.csv
S5502015VP072020121620.csv
S5502015VP072020122314.csv
S5502015VP092020122045.csv
> awk -F"VP" '{split($2,a,".");if(a[1]>b[$1]){b[$1]=$2}}END{for(i in b)print i"VP"b[i]}' temp
CBC5502015VP102020122045.csv
S5502015VP092020122045.csv
APC5502015VP092020121451.csv