簡體   English   中英

需要使用 Shell 腳本從目錄中選擇最新文件

[英]Need to pick Latest File From a Dir Using Shell Script

我是 Shell 腳本的新手,我需要使用 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 腳本從目錄中選擇這三個文件

你能幫我解決這個問題嗎?

僅使用 bash 安全地執行此操作將非常有問題。 正如喬納森所提到的,像空格或換行符這樣的“特殊”字符可能會阻塞你的腳本。

如果我們可以假設不會有任何這些,那么我們可以在 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

正如我所說,這不處理文件名中的換行符。

還要注意,這使用了revsort ,它們不是 bash 內置的。 rev部分可以在內部完成,使用更多代碼,這可能會使它們執行得更快,但您只會在非常極端的情況下看到差異。 我們對sort無能為力,因為 bash 中沒有內置。

這個 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

這是 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM