Хранение количества файлов в папке, постоянной путем удаления старых файлов

Можно установить программное обеспечение Enterprise Target iSCSI и установить iSCSI LUN из редкого файла как так:

В/etc/iet/ietd.conf:

Target iqn.my.iscsi.test:disk1
        Lun 0 Path=/path/to/my/sparse_file,Type=fileio

Затем инициируйте цель от хоста, на котором необходимо восстановить. Так как цель покажет локальным устройством (например,/dev/sdd), Вы можете dd с того устройства на Ваше локальное устройство.

4
01.02.2014, 09:58
4 ответа

Я выполнил команду:

find /mnt/md0/capture/DCN/ -maxdepth 1 -type f -name "*.pcap" -print0 |
  xargs -0 ls -lt | tail -n "$del" | awk '{print $8}'

Проблема, которую я наблюдал, была этим awk '{print $8}' печатает время, не имя файла. awk '{print $9}' решил бы это.

Другой проблемы является этим xargs может работать ls -lt несколько раз, который давал бы Вам много отсортированных списков файлов один за другим, но целый список не будет отсортирован.

Но, кажется, существуют другие упрощения, которые можно было сделать. Можно получить самые старые файлы с:

ls -dt /mnt/md0/capture/DCN/*.pcap | tail -n "$del"

Это принимает, поскольку Ваше сообщение казалось, что имена файлов не имеют никаких пробелов, вкладок или символов новой строки в них.

Так, полная команда для удаления самого старого $del файлы могли быть:

ls -dt /mnt/md0/capture/DCN/*.pcap | tail -n "$del" | xargs rm

Еще: Если Ваши имена файлов могут содержать пробелы, вкладки, обратные косые черты или кавычки в них (но не новые строки), используют (принятие GNU ls 4.0 (1998) или более новый):

ls -dt --quoting-style=shell-always /mnt/md0/capture/DCN/*.pcap |
  tail -n "$del" | xargs rm
2
27.01.2020, 20:50
  • 1
    команда ls имеет предел на то, сколько можно показать файлы? я имею в виду, делает ulimit-s, влияют на это? –  Jishnu U Nair 31.01.2014, 10:47
  • 2
    @JishnuUNair я работал ls -t на каталоге с 50 000 файлов без проблемы с помощью размера стека по умолчанию 8 192. После, уменьшая размер стека с ulimit -s 100, ls-t на 50 000 файлов все еще хорошо работал. –  John1024 31.01.2014, 10:59
  • 3
    Это не только новые строки, которые являются проблемой с xargs, это - пространство, вкладка, одинарная кавычка, двойная кавычка и обратная косая черта также. Также отметьте это ls мог бы не выполниться, если список файлов является большим. –  Stéphane Chazelas 31.01.2014, 11:54
  • 4
    @StephaneChazelas OK, я добавил решение для пробелов, вкладок, одинарные кавычки, двойные кавычки и обратные косые черты. В моих тестах, ls хорошо работавший на 50,000 + файлы, что OP требуется. При каких обстоятельствах это перестанет работать? –  John1024 31.01.2014, 22:22
  • 5
    Как все решения, которые имеют оболочку, разворачивают подстановочный знак в аргументах команде, это может достигнуть, предел на размер arguments+environment передал команде. Это будет зависеть от количества аргумента и их размера и системы и версии. –  Stéphane Chazelas 31.01.2014, 23:23

Для тех, которые не желают сделать предположения на названиях файлов:

С zsh:

#! /bin/zsh -
keep=5000
rm -f /mnt/md0/capture/DCN/*.pcap(D.om[$((keep+1)),-1])

Это использует zsh спецификаторы globbing:

  • D: включает скрытые файлы (Точечные файлы).
  • .: только регулярные файлы (как find -type f)
  • om: обратный порядок на возрасте (на основе времени изменения)
  • [$((keep+1)),-1]: только включайте 5001-е в последнее.

(это может перестать работать, если список файлов для удаления является очень большим, в этом случае можно хотеть использовать zargs разделить его или включить zshвстроенный rm с zmodload zsh/files).

С относительно последними версиями инструментов GNU:

cd /mnt/md0/capture/DCN/ &&
  find . -maxdepth 1 -name '*.pcap' -type f -printf '%T@@%p\0' |
    sort -zrn | sed -z "s/[^@]*@//;1,$keep d" | xargs -r0 rm -f

(принятие GNU sed 4.2.2 или выше (2012) для -z, GNU sort 1.14 или выше (1996) для -z)

find создает разграниченный список NUL имен файлов с предварительно ожидаемой меткой времени Unix (как 1390682991.0859627500@./file) который отсортирован по sort. sed удаляет метку времени и печатает только от 5001-й записи. Это передается как аргументы rm использование xargs -r0.

или (с любой версией инструментов GNU):

cd /mnt/md0/capture/DCN/ &&
  find . -maxdepth 1 -name '*.pcap' -type f -printf '%T@@%p\0' |
    tr '\0\n' '\n\0' | sort -rn | tail -n "+$(($keep+1))" |
    cut -d @ -f2- | tr  '\0\n' '\n\0' | xargs -r0 rm -f

То же, за исключением того, что мы используем cut удалить метку времени и tail выбрать строки, запускающиеся от 5 001. Поскольку GNU cut и tail не поддерживайте a -z работать над NUL разграничило записи, мы используем tr подкачивать новую строку и символы NUL прежде и после питания данных им.

С GNU ls (4.0 (1998) или выше), и bash:

shopt -s dotglob
cd /mnt/md0/capture/DCN/ &&
  eval "files=($(ls -dt --quoting-style=shell-always -- *.pcap))" &&
  rm -f -- "${files[@]:$keep}"

(который также может перестать работать, если список файла является большим. Также обратите внимание, что это может включать нерегулярные pcap файлы (нет -type f)).

Standardly/POSIXly/portably, это намного более хитро:

cd /mnt/md0/capture/DCN/ &&
  ls -dt ./.pcap ./.*.pcap ./*.pcap | awk -v keep="$keep" '
    function process() {
      if (++n > keep) {
        gsub(/[ \t\n"\\'\'']/,"\\\\&", file)
        print file
        file = ""
      }
    }
    /\// {
      if (NR > 1) process()
      file=$0
      next
    }
    {file = file "\n" $0}
    END {if (NR > 0) process()}' | xargs rm -f

(снова, можно достигнуть предела количества аргументов, и это не проверяет на регулярные файлы).

Хитрый бит там должен обработать имена файлов с символами новой строки. Выше, мы являемся передающими ./* кому: ls что означает / будет включен однажды для каждого имени файла, и мы используем это в awk для идентификации, на которой строке каждое имя файла запускается затем мы знаем который символ новой строки (в дополнение ко всем другим, особенным для xargs) выйти для xargs.

5
27.01.2020, 20:50
  • 1
    Ваше первое решение не работает, поскольку в Linux не говорится 'zsh найденный интерпретатор'. И я также попробовал другие два, они вмятина, выполненная также. –  Jishnu U Nair 31.01.2014, 10:20
  • 2
    @Jishnu, Вы могли бы хотеть установить zsh прежде чем Вы попытаетесь использовать его... –  Graeme 31.01.2014, 13:56
  • 3
    Для тех, которые пробуют это, обратите внимание, что debian (Хрипящая) конюшня имеет sed версия 4.2.1, которая не предлагает -z. –  John1024 31.01.2014, 22:32

Просто используйте ls с убывающим, отсортировав -t:

limit=5000
Cnt=0
for line in `ls -t`
do
  if [[ $Cnt -gt $limit ]]
  then
    rm $line
  fi
  Cnt=`expr $Cnt + 1`
done
0
27.01.2020, 20:50
  • 1
    не разделяет на новой строке, она разделяет на пробелах (она также выполняет поколение имени файла). –  Stéphane Chazelas 31.01.2014, 12:05

Принятие ни одни из имен файлов не содержат пространство, вкладку, новую строку, одинарная кавычка, двойная кавычка или символы обратной косой черты, это удаляет самые старые файлы выше предела

mkdir t && cd t

# 50500 files, 500 to delete
touch {000001..050500}

limit=50000

ls -t|tail -n "+$(($limit + 1))"|xargs rm 

ls|wc -l
50000

tail -n +50001 выставочные файлы выше предела.

1
27.01.2020, 20:50

Теги

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