Удалить файлы — сохранить самые новые на основе шаблона имени файла

Это работает для меня

apt-get install software-properties-common
add-apt-repository "deb http://ppa.launchpad.net/webupd8team/java/ubuntu xenial main"
apt-get update
apt-get install oracle-java8-installer

справочное руководство

1
29.04.2019, 16:46
4 ответа

Здесь нет особой необходимости в bash; простой скрипт shможет сделать это, дважды используя позиционный массив. Внешний цикл выбирает все нужные файлы данных (подстановочные знаки для частей идентификатора и даты ); он извлекает часть идентификатора, а затем запускает подоболочку для перебора всех файлов с этим идентификатором. Затем эта подоболочка перебирает естественно отсортированный по дате -список этих файлов и удаляет все, кроме последнего, сохраняя самый новый.

#!/bin/sh

set -- *_data_*.csv
for f in "$@"
do
  id=${f%%_*}
  # a subshell so we don't clobber $@
  (
        set -- "${id}"_data_*.csv
        while [ "$#" -gt 1 ]
        do
          rm -- "$1"
          echo "DELETE: $1"
          shift
        done
  )
done

Я добавил оператор echo... DELETE, чтобы продемонстрировать результаты для указанных вами имен файлов:

DELETE: 10020209_data_2019-04-23_001.csv
DELETE: 10020209_data_2019-04-24_001.csv
DELETE: 10020209_data_2019-04-25_001.csv
DELETE: 10020209_data_2019-04-26_001.csv
DELETE: 10020209_data_2019-04-27_001.csv
DELETE: 10020272_data_2019-04-23_001.csv
DELETE: 10020272_data_2019-04-24_001.csv
DELETE: 10020272_data_2019-04-25_001.csv
DELETE: 10020272_data_2019-04-26_001.csv
DELETE: 10020272_data_2019-04-27_001.csv
2
27.01.2020, 23:30

Вы также можете сделать это с помощью последовательности команд в одной строке -, если у вас есть mktemp, tee, sort, grep, xargsи, конечно же, rmдоступны в вашей системе. Если у вас нет tac, вы можете заменить его наsort -r:

(temp_all=$(mktemp) && temp_last=$(mktemp) && { tac | tee $temp_all | sort -un > $temp_last ; } && grep -vf $temp_last $temp_all ; rm -f $temp_last $temp_all)

Вышеприведенный код предполагает полный список файлов в стандартном вводе (, он может быть получен любым способом, который вы считаете нужным, find, ls, файл и т. д. )и показывает список файлов удалить. Затем вы можете передать такой список вxargs rm

В разобранном виде:

(
temp_all=$(mktemp) && \
temp_last=$(mktemp) && \ # make a couple of temp files
{ 
    tac | \              # reverse the list of files and...
    tee $temp_all | \    # pipe it into one temp entirely and also...
    sort -un > $temp_last ; \ # into a sort that makes names unique into the other temp
} && \
    grep -vFf $temp_last $temp_all ; \ # use grep to filter out names
rm -f $temp_last $temp_all  # remove temp files
)

Это может иметь дело с любым количеством входных имен, но требует, чтобы ни одно имя не содержало встроенных новых строк. Это кажется разумным для вашего случая.

0
27.01.2020, 23:30
Put all file names in l.txt
Proceed with below steps and it worked fine

da=`awk -F "_" '{print $3}' l.txt | sort | uniq| sort -nr| sed -n '1p'`


 for id in `awk -F "_" '{print $3}' l.txt | sort | uniq`
> do
> find  path -maxdepth 1 -type f -newermt $da -iname "$id*"  | sed -n '2,$p'| awk '{print "rm" " " $1}'| sh;done
0
27.01.2020, 23:30

Я знаю, что ответов уже много, но здесь как альтернатива на Python. Вам не нужно перебирать файлы дважды.

#!/usr/bin/env python                                                           

import os
import glob

if __name__ == '__main__':
    newest_dict = dict()

    for f in glob.glob('*.csv'):
        id = f[:8]

        if id not in newest_dict:
            newest_dict[id] = f
        else:
            nf = newest_dict[id]

            f_ts = f[14:24]
            nf_ts = nf[14:24]

            if f_ts > nf_ts:
                newest_dict[id] = f
                print("Deleting", nf)
                os.remove(nf)                                                  
            else:
                print("Deleting", f)
                os.remove(f)
0
27.01.2020, 23:30

Теги

Похожие вопросы