Я пытаюсь удалить самые старые файлы в каталоге, если в каталоге есть 8 файлов. - PullRequest
2 голосов
/ 27 сентября 2019

Я пытаюсь удалить самые старые файлы в каталоге, если в каталоге есть 8 файлов.

ls -Ct /tmp/test/ | awk '{$1=$2=$3=$4=""; print $0}' | xargs rm

Я хотел бы удалить вывод:

ls -Ct /tmp/test/ | awk '{$1=$2=$3=$4=""; print $0}' 

, но я получаю сообщение об ошибке, показывающее, что эти файлы не существуют.Я знаю, что это потому, что xargs ищет в каталоге, в котором я сейчас нахожусь, но мне нужно, чтобы он выглядел из / tmp / test /.Есть ли способ сделать это?

Ответы [ 6 ]

1 голос
/ 27 сентября 2019

Я собираюсь предположить, что вы оставляете 8 новых файлов и удаляете остальные.

$ mkdir test
$ cd test
$ touch "0 0"
$ for i in $(seq 1 10) ; do touch $i ;sleep 1 ; done
$ touch "a a"
$ ls -t
ls -t1 | sed -n '9,$p' | while read f; do rm "$f" ; done
$ ls -t1
a a
10
9
8
7
6
5
4
1 голос
/ 27 сентября 2019

Если вы хотите использовать , это легко сделать с помощью двух команд:

$ t=$(find . -maxdepth 1 -type f -printf "%T@\n" | sort -rg | awk '(NR==9)')
$ [[ "$t" != "" ]] && find . -maxdepth 1 -type f ! -newermt "@${t}" -delete

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

Если вы хотите сделать это в , вы можете сделать следующее:

$ files=( *(.om) )
$ (( ${#files[9,-1]} != 0 )) && rm "${files[9,-1]}"

Это создает файлы массивов, которые содержат файлы (.), отсортированные (om) по времени модификации.Затем мы выбираем файлы, начиная с позиции 9 до конца.Чтобы быть в безопасности, мы сначала проверяем, есть ли файлы в этом подсписке.

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

1 голос
/ 27 сентября 2019

Вы написали , чтобы удалить самые старые файлы в каталоге, если имеется 8 файлов .Я не совсем уверен, что вы подразумеваете под этим, но Я собираюсь предположить, что вы оставляете 8 новейших файлов и удаляете остальные .Кроме того, поскольку вы пометили awk, я использую GNU awk (для stat()) для этой работы.

Первый тестовый материал:

$ mkdir test                                                  # create test dir
$ cd test                                                     # use it
$ for i in $(seq 1 10 | shuf) ; do touch $i ;sleep 1 ; done   # touch some test files
$ ls -t                                                       # 1 possible distribution
8  10  6  7  1  2  4  9  3  5

Программа gawk:

$ gawk '
@load "filefuncs"                                    # enable stat()
BEGIN {
    for(i=1;i<ARGC;i++) {                            # iterate argument files
        ret=stat(ARGV[i],fdata)                      # use stat to get the mtime
        mtimes[ARGV[i]]=fdata["mtime"]               # hash to an array
    }
    PROCINFO["sorted_in"]="@val_num_desc"            # set for traverse order to newest first
    for(f in mtimes)                                 # use that order
        if(++c>8)                                    # leave 8 newest
            cmd=cmd OFS f                            # gather the list of files to rm
    if(cmd) {                                        # if any
        cmd="rm -f" cmd                              # add rm to the beginning
        print cmd                                    # print the command to execute
        # # # system(cmd)                            # this is the actual remove command
    }                                                # by uncommenting it you admit you 
}' *                                                 # understand how the script works 
                                                     # and accept all responsibility
0 голосов
/ 27 сентября 2019

как насчет

$ ls -t | tail +9 | xargs rm

сортировать файлы по времени, список выбрать из 9-го и удалить.Если для менее чем 8 файлов вы не хотите видеть ошибку rm, просто добавьте параметр -f.

0 голосов
/ 27 сентября 2019

Предполагая, что имена файлов не содержат табуляции или новых строк, попробуйте следующее:

dir="/tmp/test"

while IFS= read -r line; do
    files+=( "$line" )
done < <(find "$dir" -maxdepth 1 -type f -printf "%T@\t%p\n" | sort -n -k 1 -t $'\t' | cut -f 2)

(( ${#files[@]} < 8 )) && exit
n=8

# try the following to remove the oldest n files
rm -- "${files[@]:0:$n}"

# try the following to keep the newest n files and remove older ones
m=$(( ${#files[@]} - n ))
rm -- "${files[@]:$m:$n}"

Как указывает @JamesBrown, мне не ясно, сколько файлов следует удалить или оставить.Пожалуйста, попробуйте любой из вышеперечисленных вариантов в зависимости от ваших требований.

0 голосов
/ 27 сентября 2019

Вы можете использовать:

read filename < <(ls -rt)

, чтобы узнать самый старый файл (или каталог) в переменной filename .

Эта строка вызывает ls (1) длясоздать список файлов, упорядоченных по времени (-t) в обратном порядке (-r): первое возвращенное имя файла будет самым старым.

Чтобы узнать, сколько файлов (или каталогов) существует, вы можете использовать:

ls | wc -w

Надеюсь, это поможет.

...