Para aqueles que não querem fazer suposições sobre os nomes dos arquivos:
com zsh
:
#! /bin/zsh -
keep=5000
rm -f /mnt/md0/capture/DCN/*.pcap(D.om[$((keep+1)),-1])
Usando os qualificadores zsh
globbing:
-
D
: inclui arquivos ocultos ( D ot files).
-
.
: somente arquivos regulares (como find
's -type f
)
-
om
: inverte o rder na idade (com base no m tempo de odificação)
-
[$((keep+1)),-1]
: inclua apenas o 5001 st até o último.
(pode falhar se a lista de arquivos a serem removidos for muito grande, caso em que você poderá usar zargs
para dividi-lo ou ativar% built_ zsh
with rm
).
Com versões relativamente recentes de ferramentas GNU:
cd /mnt/md0/capture/DCN/ &&
find . -maxdepth 1 -name '*.pcap' -type f -printf '%T@@%pcd /mnt/md0/capture/DCN/ &&
find . -maxdepth 1 -name '*.pcap' -type f -printf '%T@@%pshopt -s dotglob
cd /mnt/md0/capture/DCN/ &&
eval "files=($(ls -dt --quoting-style=shell-always -- *.pcap))" &&
rm -f -- "${files[@]:$keep}"
' |
tr '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
\n' '\n#! /bin/zsh -
keep=5000
rm -f /mnt/md0/capture/DCN/*.pcap(D.om[$((keep+1)),-1])
' | sort -rn | tail -n "+$(($keep+1))" |
cut -d @ -f2- | tr 'cd /mnt/md0/capture/DCN/ &&
find . -maxdepth 1 -name '*.pcap' -type f -printf '%T@@%pcd /mnt/md0/capture/DCN/ &&
find . -maxdepth 1 -name '*.pcap' -type f -printf '%T@@%pshopt -s dotglob
cd /mnt/md0/capture/DCN/ &&
eval "files=($(ls -dt --quoting-style=shell-always -- *.pcap))" &&
rm -f -- "${files[@]:$keep}"
' |
tr '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
\n' '\n%pre%' | sort -rn | tail -n "+$(($keep+1))" |
cut -d @ -f2- | tr '%pre%\n' '\n%pre%' | xargs -r0 rm -f
' |
sort -zrn | sed -z "s/[^@]*@//;1,$keep d" | xargs -r0 rm -f
\n' '\n%pre%' | xargs -r0 rm -f
' |
sort -zrn | sed -z "s/[^@]*@//;1,$keep d" | xargs -r0 rm -f
(assumindo o GNU sed 4.2.2 ou acima (2012) para zmodload zsh/files
, GNU -z
1.14 ou acima (1996) para sort
)
-z
cria uma lista delimitada por NUL de nomes de arquivos com um registro de data e hora Unix prefixado (como find
) que é classificado por 1390682991.0859627500@./file
. sort
remove o registro de data e hora e imprime apenas a partir do registro 5001 st . Isso é passado como argumentos para sed
usando rm
.
ou (com qualquer versão das ferramentas GNU):
%pre%
O mesmo, exceto que estamos usando xargs -r0
para remover o registro de data e hora e cut
para selecionar as linhas a partir de 5001. Como o GNU tail
e cut
não suportam tail
para trabalhar Registros delimitados por NUL, usamos -z
para trocar os caracteres de nova linha e NUL antes e depois de fornecer os dados para eles.
Com o GNU tr
(4.0 (1998) ou superior) e ls
:
%pre%
(que também pode falhar se a lista de arquivos for grande. Observe também que pode incluir arquivos pcap não regulares (sem bash
)).
Standard / POSIXly / portably, isso é muito mais complicado:
%pre%
(mais uma vez, você pode atingir o limite do número de argumentos e não verificar arquivos regulares).
O problema é o de lidar com os nomes de arquivos com caracteres de nova linha. Acima, estamos passando -type f
para ./*
, o que significa que ls
será incluído uma vez para cada nome de arquivo, e usamos isso em /
para identificar em qual linha cada nome de arquivo é iniciado, sabemos qual caractere de nova linha (além de todos os outros especiais para awk
) para escapar por xargs
.