En son X dosyaları hariç tümünü bash'de sil


157

Bir dizinden en son X dosyaları hariç tüm dosyaları silmek için bir komut çalıştırmak için bash ile oldukça standart bir UNIX ortamında basit bir yolu var mı?

Biraz daha somut bir örnek vermek için, bazı cron işlerinin bir dizine her saatte bir dosya (örneğin, bir günlük dosyası veya hedeflenmiş yedekleme) yazdığını hayal edin. 5'ten az olana kadar bu dizindeki en eski dosyaları kaldıracak başka bir cron işi çalıştırmak için bir yol istiyorum.

Ve net olmak gerekirse, sadece bir dosya var, asla silinmemelidir.

Yanıtlar:


117

Mevcut cevaplarla ilgili sorunlar:

  • gömülü boşluk veya satırsonu içeren dosya adlarını işleyememe.
    • rmdoğrudan sıralanmamış bir komut ikamesi ( rm `...`) için çağrılan çözümler söz konusu olduğunda , istenmeyen globbing riski eklenir.
  • dosya ve dizinleri birbirinden ayırt edememe (yani, dizinler en son değiştirilen 5 dosya sistemi öğesi arasında yer alsaydı, etkin olarak 5'ten az dosya tutarsınız rmve dizinlere başvurmak başarısız olur).

wnoise cevabı adresleri bu meseleler, ancak çözüm GNU -özel (ve oldukça karmaşık).

İşte tek bir uyarı ile gelen pragmatik, POSIX uyumlu bir çözüm : gömülü yeni satırlarla dosya adlarını işleyemez - ancak çoğu insan için gerçek bir dünya endişesi olduğunu düşünmüyorum.

Kayıt için, lsçıktıyı ayrıştırmanın neden genellikle iyi bir fikir olmadığının açıklaması şudur : http://mywiki.wooledge.org/ParsingLs

ls -tp | grep -v '/$' | tail -n +6 | xargs -I {} rm -- {}

Yukarıdakiler verimsizdir , çünkü her dosya adı için bir kez xargsçağırmak zorundadır . Platformlarınız bu sorunu çözmenize izin verebilir:rm
xargs

Eğer varsa , GNU xargs , kullanımı -d '\n'markaları, xargsher giriş satırı ayrı argüman düşünün, henüz bir komut satırında sığacak sayıda argüman olarak geçer seferde :

ls -tp | grep -v '/$' | tail -n +6 | xargs -d '\n' -r rm --

-r( --no-run-if-empty) rmherhangi bir girdi yoksa çağrılmamasını sağlar .

Eğer varsa BSD xargs (dahil olmak üzere MacOS ), kullanabilirsiniz -0işlemek için NULilk çeviri satırbaşıyla sonra, -separated girişi NUL( 0x0) karakter, aynı zamanda (genellikle) geçtiği tüm dosya adları. Kerede (will da GNU çalışma xargs):

ls -tp | grep -v '/$' | tail -n +6 | tr '\n' '\0' | xargs -0 rm --

Açıklama:

  • ls -tpdosya sistemi öğelerinin adlarını, değiştirildikleri süreye göre, azalan düzende (en son değiştirilen öğeler ilk sırada) ( -t), dizinleri bu /şekilde işaretlemek için bir izle yazdırılmış olarak ( ) sıralayarak yazdırır -p.
  • grep -v '/$'daha sonra, -vizleyen /( /$) satırları ( ) atlayarak dizinleri sonuç listesinden kaldırır .
    • Uyarı : Bir yana bir dizine noktaları o sembolik bağ teknik olarak bir dizin kendisi değil, bu tür sembolik bağlar olacak değil dışlanamaz.
  • tail -n +6İlk atlar 5 tüm dönen aslında, listesinde girdileri ancak 5 en son değiştirilen dosyalar varsa. Dosyaları
    hariç tutmak için N, N+1iletilmesi gerektiğini unutmayın tail -n +.
  • xargs -I {} rm -- {}(ve varyasyonları) daha sonra rmtüm bu dosyaları çağırır ; hiç eşleşme xargsyoksa hiçbir şey yapmaz.
    • xargs -I {} rm -- {}{}her girdi satırını bir bütün olarak temsil eden yer tutucuyu tanımlar , bu nedenle rmdaha sonra her girdi satırı için bir kez çağrılır, ancak gömülü boşlukları doğru şekilde işlenmiş dosya adları vardır.
    • --her durumda başlamak başına herhangi dosya adları olmasını sağlar -yanlışlıkla olmayan seçenekler ile rm.

Eşleşen dosyaların ayrı ayrı işlenmesi veya bir kabuk dizisinde toplanması gerektiğinde orijinal sorundaki bir değişiklik :

# One by one, in a shell loop (POSIX-compliant):
ls -tp | grep -v '/$' | tail -n +6 | while IFS= read -r f; do echo "$f"; done

# One by one, but using a Bash process substitution (<(...), 
# so that the variables inside the `while` loop remain in scope:
while IFS= read -r f; do echo "$f"; done < <(ls -tp | grep -v '/$' | tail -n +6)

# Collecting the matches in a Bash *array*:
IFS=$'\n' read -d '' -ra files  < <(ls -tp | grep -v '/$' | tail -n +6)
printf '%s\n' "${files[@]}" # print array elements

2
Buradaki diğer cevaplardan kesinlikle daha iyi, bu yüzden newline davasını görmezden gelmek için sadece dikkatli bir şekilde bir şey olduğunu düşündüğümde bile desteğimi vermekten mutluluk duyuyorum.
Charles Duffy

2
Bunu yaparsanız lsgeçerli dizinde değilse, o dosyalara yolları içerecektir '/', hangi araçları grep -v '/'şey uymaz. grep -v '/$'Sadece dizinleri hariç tutmak istediğiniz şey olduğuna inanıyorum .
waldol1

1
@ waldol1: Teşekkürler; Cevabı önerilerinizi içerecek şekilde güncelledik, bu da grepkomutu kavramsal olarak daha net hale getiriyor . Ancak, açıkladığınız sorunun tek bir dizin yolu ile ortaya çıkmayacağını unutmayın ; örneğin, ls -p /private/varyalnızca yalnızca dosya adları yazdırır. Yalnızca birden çok dosya bağımsız değişkenini (genellikle bir glob aracılığıyla) geçtiyseniz , çıktıdaki gerçek yolları görürsünüz; ör. ls -p /private/var/*(ve siz eklemediyseniz, eşleşen alt dizinlerin içeriğini de görürsünüz -d).
mklement0

108

Bir dizindeki en son 5 dosyanın tümünü (veya herhangi bir sayıyı) kaldırın.

rm `ls -t | awk 'NR>5'`

2
Sadece arşiv dosyalarımı dikkate almak için buna ihtiyacım vardı. değişim ls -tiçinls -td *.bz2
James T Snell

3
Ben rm -rf ls -t | awk 'NR>1'(sadece en son istedim) olarak değiştirerek bu dizinler için kullanılır . Teşekkürler!
lohiaguitar91

11
ls -t | awk 'NR>5' | xargs rm -f boruları tercih ederseniz ve silinecek hiçbir şey yoksa hatayı bastırmanız gerekir.
H2ONaCl

16
Kısa ve okunabilir, belki de ama kullanımı tehlikeli; ile oluşturulmuş bir dosyayı silmeye çalışırsanız touch 'hello * world', bu geçerli dizindeki her şeyi siler .
Charles Duffy

1
Bu 2008 yılında cevaplanmış olmasına rağmen bir cazibe ve sadece belirli bir dizinden eski yedekleri silmek için gerekli olan gibi çalışır. Muhteşem.
Rens Tillmann

86
(ls -t|head -n 5;ls)|sort|uniq -u|xargs rm

Bu sürüm boşluklu adları destekler:

(ls -t|head -n 5;ls)|sort|uniq -u|sed -e 's,.*,"&",g'|xargs rm

20
Bu komut, adlarında boşluk bulunan dosyaları doğru işlemez.
tylerl

5
(ls -t|head -n 5;ls)bir komut grubudur . En son 5 dosyayı iki kez yazdırır. sortözdeş çizgileri bir araya getirir. uniq -uyinelenenleri kaldırır, böylece en son 5 dosya dışındaki tüm dosyalar kalır. her birini xargs rmçağırır rm.
Fabien

15
Bu, 5 veya daha azınız varsa tüm dosyalarınızı siler! Lütfen --no-run-if-emptyolduğu xargsgibi ekleyin (ls -t|head -n 5;ls)|sort|uniq -u|xargs --no-run-if-empty rmcevabı güncelleyin.
Gonfi den Tschal

3
"Boşluklu isimleri destekleyen" bile tehlikelidir. Değişmez tırnak işaretleri içeren bir ad düşünün: touch 'foo " bar'komutun geri kalanının tamamını atar.
Charles Duffy

2
... Kullanımda daha güvenlidir xargs -d $'\n'(dışında bir şey kullanarak gerektirir giriş akışı NUL-sınırlayan olsa içerik içine enjekte tırnak daha lshiç gerçekten doğru yapmak) ideal bir seçenektir.
Charles Duffy

59

Thelsdj'nin cevabının daha basit çeşidi:

ls -tr | head -n -5 | xargs --no-run-if-empty rm 

ls -tr, tüm dosyaları en eskiden görüntüler (-t en yenisi, -r geri).

head -n -5 son 5 satır dışındaki tüm satırları görüntüler (yani en yeni 5 dosya).

xargs rm seçilen her dosya için rm'yi çağırır.


15
Xargs dosyasına --no-run-if-empty eklemeniz gerekir, böylece 5'ten az dosya olduğunda başarısız olmaz.
Tom

ls -1tr | kafa -n -5 | xargs rm <---------- ls'ye -1 eklemeniz gerekir ya da başın düzgün çalışması için bir liste çıktısı almazsınız
Al Joslin

3
@AlJoslin, -1çıktı bir boru hattında olduğunda varsayılan değer olduğundan, burada zorunlu değildir. Bu, xargsadları boşluk, tırnak işareti ve c ile ayrıştırırken varsayılan davranışı ile ilgili çok daha büyük sorunlara sahiptir .
Charles Duffy

Görünüşe göre --no-run-if-emptybenim kabuğumda tanınmadı. Windows'ta Cmder kullanıyorum.
StayFoolish

-0Dosya adları beyaz boşluk içeriyorsa seçeneği kullanmanız gerekebilir . Henüz test etmedim. kaynak
Keith

18
find . -maxdepth 1 -type f -printf '%T@ %p\0' | sort -r -z -n | awk 'BEGIN { RS="\0"; ORS="\0"; FS="" } NR > 5 { sub("^[0-9]*(.[0-9]*)? ", ""); print }' | xargs -0 rm -f

-Printf için GNU bulma ve -z için GNU sıralama ve "\ 0" için GNU awk ve -0 için GNU xargs gerektirir, ancak katıştırılmış yeni satırlara veya boşluklara sahip dosyaları işler.


2
Dizinleri kaldırmak istiyorsanız, -f'yi -d olarak değiştirin ve rm'ye bir -r ekleyin. bulmak. -maxdepth 1-tipi d -printf '% T @% p \ 0' | sıralama -r -z -n | awk 'BEGIN {RS = "\ 0"; ORS = "\ 0"; FS = ""} NR> 5 {alt ("^ [0-9] * (. [0-9] *)?", ""); yazdır} '| xargs -0 rm -rf
alex

1
Bir bakışta, awkmantığın karmaşıklığına (veya bu nedenle, gerekliliğe) şaşırdım . OP sorusu içinde bunu gerekli kılan bazı gereklilikler eksik mi?
Charles Duffy

@Charles Duffy: sub (), üzerinde sıralanmış olan zaman damgasını kaldırır. "% T @" tarafından üretilen zaman damgası bir kesir kısmı içerebilir. FS ile boşlukta bölme, gömülü boşluklu yolları keser. İlk uzay çalışmalarıyla kaldırmayı düşünüyorum, ama okumak neredeyse zor. RS ve ORS ayırıcılar komut satırında ayarlanamaz, çünkü bunlar NUL'dur.
wnoise

1
@wnoise, bu benim her zamanki yaklaşım bir kabuk while read -r -d ' '; IFS= -r -d ''; do ...döngü içine boru - ilk okuma uzayda sona erer, ikincisi NUL devam ediyor.
Charles Duffy

@Charles Duffy: Her zaman ham kabuğun temkinliyim, belki de bizans alıntılarından dolayı. Şimdi GNU'nun sed -z -e 's/[^ ]* //; 1,5d'en açık olduğunu düşünüyorum . (ya da belki sed -n -z -e 's/[^ ]* //; 6,$p'.
wnoise

14

Geçerli dizinde dizin olduğunda tüm bu yanıtlar başarısız olur. İşte işe yarayan bir şey:

find . -maxdepth 1 -type f | xargs -x ls -t | awk 'NR>5' | xargs -L1 rm

Bu:

  1. geçerli dizinde dizin olduğunda çalışır

  2. önceki dosya kaldırılamasa bile her bir dosyayı kaldırmaya çalışır (izinler vb. nedeniyle)

  3. Geçerli dizindeki dosyaların sayısı aşırı olduğunda ve güvenli başarısız xargsolur normalde (üzerinize vida -x)

  4. dosya adlarındaki alanlara hitap etmiyor (belki de yanlış işletim sistemini kullanıyorsunuz?)


5
findTek bir komut satırına iletilenden daha fazla dosya adı döndürürse ne olur ls -t? (İpucu: ls -tKüresel olarak doğru bir sıralama düzenine sahip olmak yerine, her biri yalnızca ayrı ayrı sıralanan birden fazla işlem alırsınız ; bu nedenle, yeterince büyük dizinlerle çalışırken bu cevap kötü bir şekilde kırılır).
Charles Duffy

12
ls -tQ | tail -n+4 | xargs rm

Dosya adlarını her bir dosya adını vererek değişiklik zamanına göre listeleyin. İlk 3'ü (en son 3'ü) hariç tutun. Kalanları kaldırın.

Mklement0 (teşekkürler!) 'Dan faydalı yorumdan sonra DÜZENLE: düzeltilmiş -n + 3 bağımsız değişkeni ve dosya adları yeni satır içeriyorsa ve / veya dizin alt dizin içeriyorsa bunun beklendiği gibi çalışmayacağını unutmayın.


Bu -Qseçenek makinemde görünmüyor.
Pierre-Adrien Buisson

4
Hmm, seçenek yaklaşık 20 yıldır GNU çekirdek uygulamalarında olmuştur, ancak BSD varyantlarında belirtilmemiştir. Mac'te misin?
Mark

Gerçekten de öyleyim. Güncel sistemler arasında bu tür temel komutlar için farklılıklar olduğunu düşünmemiştim. Cevabınız için teşekkürler !
Pierre-Adrien Buisson

3
@ Mark: ++ için -Q. Evet, -Qbir GNU (burada olduğu POSIX lsSpec ). Küçük bir uyarı (nadiren uygulamada bir sorun): dosya adlarındaki -Qgömülü yeni satırları değişmez olarak kodlar \n, rmtanımaz. İlk dışlamak için 3 , xargsargüman zorunluluk +4. Son olarak, diğer birçok cevap için de geçerli olan bir uyarı: komutunuz yalnızca geçerli dizinde alt dizin yoksa amaçlandığı gibi çalışacaktır .
mklement0

1
Remove bir şey yok olduğunda, birlikte çağrı xargs sahip --no-run-if-emptyseçeneği:ls -tQ | tail -n+4 | xargs --no-run-if-empty rm
Olivier Lecrivain

8

Yeni satırları yok saymak güvenliği ve iyi kodlamayı yok saymaktır. wnoise tek iyi cevaba sahipti. Dosya adlarını $ x dizisine koyan bir varyasyon

while IFS= read -rd ''; do 
    x+=("${REPLY#* }"); 
done < <(find . -maxdepth 1 -printf '%T@ %p\0' | sort -r -z -n )

2
Temizlemenizi öneririm IFS- aksi takdirde dosya adlarından gelen boşlukları kaybetme riskiyle karşı karşıya kalırsınız. Bunu okuma komutuna dahil edebilir:while IFS= read -rd ''; do
Charles Duffy

1
neden "${REPLY#* }"?
msciwoj

4

Dosya adlarında boşluk yoksa, bu işe yarar:

ls -C1 -t| awk 'NR>5'|xargs rm

Dosya adlarında boşluk varsa,

ls -C1 -t | awk 'NR>5' | sed -e "s/^/rm '/" -e "s/$/'/" | sh

Temel mantık:

  • dosyaların zaman sırasına göre bir listesini alın, bir sütun
  • ilk 5 hariç hepsini al (bu örnek için n = 5)
  • ilk sürüm: bunları rm'ye gönderin
  • ikinci sürüm: gen düzgün bir şekilde kaldıracak bir komut dosyası

while readBoşluklarla uğraşma hilesini unutmayın : ls -C1 -t | awk 'NR>5' | while read d ; do rm -rvf "$d" ; done
pinkeen

1
@pinkeen, orada verilen kadar güvenli değil. while IFS= read -r dbiraz daha iyi olur - -rönler tarafından tüketilen gelen hazır bilgi kullanılan karakterler readve IFS=önler otomatik boşluk akıtma kesme.
Charles Duffy

4
BTW, eğer düşman dosya isimleri konusunda endişeleniyorsa, bu son derece tehlikeli bir yaklaşımdır. İle oluşturulmuş bir dosya düşünün touch $'hello \'$(rm -rf ~)\' world'; dosya adındaki değişmez tırnaklar, eklediğiniz değişmez tırnaklara karşılık gelir sedve dosya adı içindeki kod yürütülür.
Charles Duffy

1
(açık olmak gerekirse, yukarıdaki "bu" | sh, kabuk enjeksiyon güvenlik açığı olan forma atıfta bulunuyordu ).
Charles Duffy

2

Zsh ile

Mevcut dizinleri umursamadığınızı ve 999'dan fazla dosyanız olmayacağını varsayarsanız (isterseniz daha büyük bir sayı seçin veya bir while döngüsü oluşturun).

[ 6 -le `ls *(.)|wc -l` ] && rm *(.om[6,999])

Olarak *(.om[6,999]), .araç dosyaları, oaraçlar sıralama, yukarı sipariş m(koyun değişikliğin tarihine göre araçlarını aerişim süreleri için veya c, Düğüm değişimi için) [6,999], dosyanın bir dizi seçer böylece ilk 5 rm etmez.


İlgi çekici, ama benim hayatım için sıralama glob niteleyicisini ( om) çalıştıramadım (denediğim herhangi bir sıralama hiçbir etki göstermedi - ne OSX 10.11.2'de (zsh 5.0.8 ve 5.1.1 ile çalıştı) , ne Ubuntu 14.04 (zsh 5.0.2)) üzerinde - ne eksik ?. O, sadece kullanım sabit koduna gerek: menzil son nokta gelince -1: Geçen girmek anlamına gelir ve dolayısıyla geri kalan tüm dosyaları içerir [6,-1].
mklement0

2

Bunun eski bir iş parçacığı olduğunu anlıyorum, ama belki birisi bundan fayda sağlayacaktır. Bu komut geçerli dizindeki dosyaları bulur:

for F in $(find . -maxdepth 1 -type f -name "*_srv_logs_*.tar.gz" -printf '%T@ %p\n' | sort -r -z -n | tail -n+5 | awk '{ print $2; }'); do rm $F; done

Bu, arama alanınızı ifadelerle eşleşen dosyalarla sınırlandırmasına izin verdiği için önceki yanıtların bazılarından biraz daha sağlamdır. İlk olarak, istediğiniz koşullara uyan dosyaları bulun. Bu dosyaları yanlarındaki zaman damgalarıyla yazdırın.

find . -maxdepth 1 -type f -name "*_srv_logs_*.tar.gz" -printf '%T@ %p\n'

Ardından, bunları zaman damgalarına göre sıralayın:

sort -r -z -n

Ardından, en son 4 dosyayı listeden çıkarın:

tail -n+5

2. sütunu (zaman damgası değil dosya adı) alın:

awk '{ print $2; }'

Ve sonra her şeyi bir for ifadesine sarın:

for F in $(); do rm $F; done

Bu daha ayrıntılı bir komut olabilir, ancak koşullu dosyaları hedefleyebilme ve bunlara karşı daha karmaşık komutları yürütebilme şansım çok daha iyi oldu.


1

Sed-Onliners ilginç cmd bulundu - Son 3 satır sil - kedi bulmak için başka bir yol için mükemmel bulmak (tamam değil) ama fikir:

 #!/bin/bash
 # sed cmd chng #2 to value file wish to retain

 cd /opt/depot 

 ls -1 MyMintFiles*.zip > BigList
 sed -n -e :a -e '1,2!{P;N;D;};N;ba' BigList > DeList

 for i in `cat DeList` 
 do 
 echo "Deleted $i" 
 rm -f $i  
 #echo "File(s) gonzo " 
 #read junk 
 done 
 exit 0

1

En son 10 (en son) dosya dışındaki tüm dosyaları kaldırır

ls -t1 | head -n $(echo $(ls -1 | wc -l) - 10 | bc) | xargs rm

10'dan az dosya varsa, hiçbir dosya kaldırılmaz ve şunlara sahip olursunuz: hata başlığı: geçersiz satır sayısı - 0

Bash ile dosya saymak için


1

Meşgul kutusu (yönlendirici) için zarif bir çözüme ihtiyacım vardı, tüm xargs veya dizi çözümleri benim için işe yaramazdı - böyle bir komut yok. find ve mtime, 10 madde ve mutlaka 10 gün hakkında konuştuğumuzdan uygun cevap değildir. Espo'nun cevabı en kısa ve en temiz ve muhtemelen en çılgınca cevaptı.

Boşluklarda hata ve hiçbir dosya silinmeyeceği zaman standart yolla çözülür:

rm "$(ls -td *.tar | awk 'NR>7')" 2>&-

Biraz daha eğitici versiyon: awk'ı farklı kullanırsak hepsini yapabiliriz. Normalde, awk den sh değişkenleri (return) geçirmek için bu yöntemi kullanın. Her zaman okunamayacağımız gibi, farklı olmaya yalvarıyorum: İşte yöntem.

Dosya adındaki boşluklarla ilgili sorun olmayan .tar dosyalarına örnek. Test etmek için, "rm" yerine "ls" yazın.

eval $(ls -td *.tar | awk 'NR>7 { print "rm \"" $0 "\""}')

Açıklama:

ls -td *.tarzamana göre sıralanmış tüm .tar dosyalarını listeler. Geçerli klasördeki tüm dosyalara uygulamak için "d * .tar" bölümünü kaldırın

awk 'NR>7... ilk 7 satırı atlar

print "rm \"" $0 "\"" bir satır oluşturur: rm "dosya adı"

eval yürütür

Kullandığımız rmiçin yukarıdaki komutu bir komut dosyasında kullanmam! Daha akıllı kullanım:

(cd /FolderToDeleteWithin && eval $(ls -td *.tar | awk 'NR>7 { print "rm \"" $0 "\""}'))

ls -tKomutun kullanılması durumunda , aşağıdaki gibi aptal örneklere herhangi bir zarar vermez: touch 'foo " bar'vetouch 'hello * world' . Gerçek hayatta böyle isimlere sahip dosyalar yarattığımızdan değil!

Kenar notu. Sh değişkenine bu şekilde geçmek istersek, baskıyı basitçe değiştirirdik (basit form, tolere edilen boşluk yok):

print "VarName="$1

değişkeni VarNamedeğerine ayarlamak için $1. Tek seferde birden çok değişken oluşturulabilir. Bu VarNamenormal bir sh değişkeni haline gelir ve normalde daha sonra bir kodda veya kabukta kullanılabilir. Yani, awk ile değişkenler oluşturmak ve bunları kabuğa geri vermek için:

eval $(ls -td *.tar | awk 'NR>7 { print "VarName=\""$1"\""  }'); echo "$VarName"

0
leaveCount=5
fileCount=$(ls -1 *.log | wc -l)
tailCount=$((fileCount - leaveCount))

# avoid negative tail argument
[[ $tailCount < 0 ]] && tailCount=0

ls -t *.log | tail -$tailCount | xargs rm -f

2
xargsolmadan -0veya sade -d $'\n'güvenilmez; bunun boşluklu bir dosyayla nasıl davrandığını gözlemleyin veya adında karakterleri alıntılayın.
Charles Duffy

0

Bunu bash kabuğuna dönüştürdüm. Kullanım: keep NUM DIRburada NUM saklanacak dosya sayısı ve DIR fırçalanacak dizindir.

#!/bin/bash
# Keep last N files by date.
# Usage: keep NUMBER DIRECTORY
echo ""
if [ $# -lt 2 ]; then
    echo "Usage: $0 NUMFILES DIR"
    echo "Keep last N newest files."
    exit 1
fi
if [ ! -e $2 ]; then
    echo "ERROR: directory '$1' does not exist"
    exit 1
fi
if [ ! -d $2 ]; then
    echo "ERROR: '$1' is not a directory"
    exit 1
fi
pushd $2 > /dev/null
ls -tp | grep -v '/' | tail -n +"$1" | xargs -I {} rm -- {}
popd > /dev/null
echo "Done. Kept $1 most recent files in $2."
ls $2|wc -l
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.