Rm, cp, mv komutları için bağımsız değişken listesi çok uzun hata


629

UNIX'te bir dizin altında birkaç yüz PDF'im var. PDF'lerin adları gerçekten uzundur (yaklaşık 60 karakter).

Aşağıdaki komutu kullanarak tüm PDF'leri birlikte silmeye çalıştığımda:

rm -f *.pdf

Aşağıdaki hatayı alıyorum:

/bin/rm: cannot execute [Argument list too long]

Bu hatanın çözümü nedir? Bu hata mvve cpkomutlar için de oluşuyor mu? Evetse, bu komutlar için nasıl çözülür?


21
Bu bağlantıyı yararlı bulabilirsiniz
another.anon.coward



4
@jww: Ve o kadar uzun yıllardır düşünmeye devam ettim ki, bash "programcılar tarafından yaygın olarak kullanılan yazılım araçları" - burada soruları sorulabilecek bir kategori!
Vicky

@Nik - "... bir betikte" eklemek zorlayıcı değil. Sorun Minimal, Complete ve Doğrulanabilir bir örneğe düşürüldüğünde , bu sadece bir komutun nasıl çalıştırılacağı ile ilgili bir sorudur. Açık bir şeyi kaçırırsam özür dilerim.
jww

Yanıtlar:


876

Bunun olmasının nedeni, bash'ın yıldız işaretini eşleşen her dosyaya genişletmesi ve çok uzun bir komut satırı üretmesidir.

Bunu dene:

find . -name "*.pdf" -print0 | xargs -0 rm

Uyarı: bu yinelemeli bir aramadır ve alt dizinlerdeki dosyaları da bulur (ve siler). Tack -femin misin onay istemiyoruz yalnızca, rm komutuna.

Komutu özyinelemesiz yapmak için aşağıdakileri yapabilirsiniz:

find . -maxdepth 1 -name "*.pdf" -print0 | xargs -0 rm

Başka bir seçenek de -deletefind'ın bayrağını kullanmaktır :

find . -name "*.pdf" -delete

7
Hayır, xargsözellikle listeyi böler ve gerekirse birkaç komut verir.
tripleee

7
@Dennis: -maxdepth 1yoldan sonraki ilk argüman olmalı.
Barton Chittenden

54
Bul, -deletebulduğu dosyaları silmek için bir bayrağa sahiptir ve olmasa bile -exec, xargs'ı çağırmak yerine (şimdi 3 işlem ve bir boru yerine tek bir işlem yerine) rm yürütmek için daha iyi bir uygulama olarak kabul edilir. -deleteveya 2 işlem ile -exec).
scragar

3
@ ÉdouardLopez ... Ama bu BOŞ sınırlandırılmış girdiyi okuyor. Ve bütün dangerous (broken, exploitable, etc.), oldukça saçma. Şüphesiz kullanırken dikkatli olmalısınız xargs, ancak tam olarak değil eval/evil.
Monica'yı eski haline getirin

4
@scragar ile -execçağırarak rmbundan eşzamanlı işlem sayısı 2 olsa da, işlem sayısı (belki eşzamanlı rm süreçlerini yürütmek olacağını bulmak), dosyaların 1 + numarası olacaktır. Kullanılan işlem sayısı xargsönemli ölçüde 2 + n'ye düşürülecektir, burada n dosya sayısından daha az sayıda işlemdir (büyük olasılıkla yolların uzunluğuna bağlı olarak dosya sayısı / 10 diyelim). Bulmanın doğrudan silme işlemi yapıldığını varsayarsak, çağrılacak -deletetek işlem kullanılmalıdır.
neuralmer

396

tl; Dr.

Komut satırı bağımsız değişkeninin boyutuyla ilgili bir çekirdek sınırlamasıdır. forBunun yerine bir döngü kullanın.

Sorunun kaynağı

Bu, sürekli execveve ARG_MAXsabit bir sistem sorunudur . Bununla ilgili çok sayıda belge var (bkz. Adam yürütmek , debian'ın wiki'si ).

Temel olarak, genişletme sınırı aşan bir komut (parametreleriyle birlikte) üretir ARG_MAX. Çekirdekte 2.6.23sınır olarak belirlendi 128 kB. Bu sabit artırıldı ve şu komutu uygulayarak değerini alabilirsiniz:

getconf ARG_MAX
# 2097152 # on 3.5.0-40-generic

Çözüm: forDöngü Kullanma

BashFAQ / 095'tefor önerildiği gibi bir döngü kullanın ve RAM / bellek alanı dışında bir sınır yoktur:

Kuru çalışma beklediğiniz şeyi siler:

for f in *.pdf; do echo rm "$f"; done

Ve yürütün:

for f in *.pdf; do rm "$f"; done

Glob, mermiler arasında güçlü ve tutarlı davranışa sahip olduğundan ( POSIX spesifikasyonunun bir parçası ) da bu taşınabilir bir yaklaşımdır .

Not: Birkaç yorumda belirtildiği gibi, bu, daha karmaşık senaryoları uyarlayabildiğinden, örneğin bir eylemden daha fazlasını yapmak istediği yerlerde gerçekten daha yavaş ancak daha sürdürülebilirdir .

Çözüm: Kullanma find

Eğer ısrar ederseniz, kullanabilirsiniz findama gerçekten xargs kullanmayın o kadar "tehlikeli (kırık, işletilebilir, vs.) girişi olmayan NUL ayrılmış okurken" :

find . -maxdepth 1 -name '*.pdf' -delete 

-maxdepth 1 ... -deleteBunun yerine kullanmak , gerekli sistem çağrılarının harici bir işlem kullanmadan kolayca yürütülmesini -exec rm {} +sağlar find, bu nedenle daha hızlı ( @chepner comment sayesinde ).

Referanslar


31
Harika cevap, tüm SO sorularının bu şekilde cevaplanması gerekir. Teşekkürler!
2015'te

1
Döngüden bahsettiğiniz için +1 for. Daha önce kullandım find, ama her zaman seçenekleri vb. Her zaman unuttuğumda nasıl yapacağımı araştırıyorum. for
IMHO'yu

3
for f in *; do rm "$f"; doneBir cazibe olarak çalışmak olarak kullanılır
abdul qayyum 16:17

3
find -execÇözelti ÇOK daha hızlı daha görünüyor fordöngü.
threeve

2
Beş yıl sonra 4.15.0 de ( 4.15.0-1019-gcptam olarak) ve sınır Linux git repo üzerinde ARG_MAX ararken, İlginçtir ki 2097152. halen gösteren bir sonuç verir 131702. olmak ARG_MAX
Matt M.

181

findbir -deleteeylemi var:

find . -maxdepth 1 -name '*.pdf' -delete

4
Bu yine de "Argüman listesi çok uzun" dönecektir. En azından benim için öyle. xargsDennis'in cevabına göre kullanmak amaçlandığı gibi çalışır.
Sergio

7
Bu bulmak bir hata gibi geliyor.
ThiefMaster

3
@Sergio da aynı sorunu yaşadı, isim kalıbı etrafındaki eksik alıntılardan kaynaklandı.
Luxian

argh, bir şeyleri bulmak için bir aracın neden silme anahtarı bile var? en azını ve aynı zamanda tehlikeli olduğunu söylemenin gereksiz olduğunu düşünen sadece benim.
mathreadler

2
@mathreadler Ortak bir kullanım durumunun -execbir grup dosyayı kaldırmak olduğu gerçeğini ele alır . -exec rm {} +aynı şeyi yapar, ancak yine de en az bir harici işlem başlatmayı gerektirir. harici bir sarıcı kullanmadan gerekli sistem çağrılarını yürütmeyi -deletesağlar find.
chepner

21

Başka bir yanıt, xargskomutları toplu olarak işlemeye zorlamaktır . Örneğin , bir seferde deletedosyalara , dizine girin ve çalıştırın:100cd

echo *.pdf | xargs -n 100 rm


4
Eğer bir mühendisseniz ve bir hata yazdıysanız, linux'daki komutu silmek için, bunun en güvenli olanı olduğuna inanıyorum 'en güvenli ve ne olduğunu biliyorum' en iyisi. Bir noktayı kaçırırsanız, şirketinizin bir dakika içinde çökmesine izin verecek süslü şeyler değil.
Yapay Olarak

1
Bunu belirli komutlar için varsayılan genişletme nasıl yapabiliriz? Bir kerede hepsine ihtiyaç
duyup duymadıkları

1
Bunun yalnızca echobir kabuk yerleşik olduğu yerde çalıştığını unutmayın . Komutu kullanırsanız, echoyine de program bağımsız değişkenleri sınırına girersiniz.
Toby Speight

14

Ya da deneyebilirsiniz:

find . -name '*.pdf' -exec rm -f {} \;

Bu, dosyaları alt dizinlerden de siler. Bunu nasıl önleyebilirim?
Vicky

@NikunjChauhan -maxdepth seçeneği ekle:find . -maxdepth 1 -name '*.pdf' -exec rm -f {} \;
Jon Lin

Ben maxdepth seçeneğini ekleyemiyorum
Vicky

Bu seçenek yukarıdaki @ Dennis'in cevabına göre (seçilen cevap) sadece Linux için bir seçenek olabilir.
jvriesem

12

Bir kerede çok sayıda dosyayı silmeye çalışıyorsanız (bugün 485.000'den fazla bir dizini sildim), muhtemelen bu hatayla karşılaşacaksınız:

/bin/rm: Argument list too long.

Sorun bir şey gibi yazarken yani rm -rf *, *“rm-rf dosya1 dosya2 dosya3 file4” ve benzeri gibi her eşleşen dosya listesi ile değiştirilir. Bu argüman listesini saklamak için ayrılmış küçük bir bellek tamponu vardır ve doldurulursa, kabuk programı yürütmez.

Bu sorunu aşmak için, birçok kişi her dosyayı bulmak için find komutunu kullanacak ve bunları tek tek “rm” komutuna aşağıdaki gibi aktaracaktır:

find . -type f -exec rm -v {} \;

Benim sorunum 500.000 dosyayı silmem gerekti ve çok uzun sürüyordu.

Dosyaları silmenin çok daha hızlı bir yoluna rastladım - “find” komutunun içinde “-delete” bayrağı var! İşte ben kullanarak sona erdi:

find . -type f -delete

Bu yöntemi kullanarak, dosyaları yaklaşık 2000 dosya / saniye hızında siliyordum - çok daha hızlı!

Dosya adlarını silerken de gösterebilirsiniz:

find . -type f -print -delete

… Ya da kaç dosyanın silineceğini, daha sonra bunların silinmesinin ne kadar süreceğini gösterin:

root@devel# ls -1 | wc -l && time find . -type f -delete
100000
real    0m3.660s
user    0m0.036s
sys     0m0.552s

Teşekkürler. Yaptığım sudo find . -type f -delete485.000 dosyaları hakkında silmek ve bu benim için çalıştı. Yaklaşık 20 saniye sürdü.
Nigel Alderton

11

bunu deneyebilirsiniz:

for f in *.pdf
do
  rm $f
done

EDIT: ThiefMaster yorum genç kabuk jedis böyle tehlikeli uygulama ifşa etmemem önerir, bu yüzden daha "daha güvenli" bir sürüm ekleyeceğim (birisi "-rf. ..Pdf" dosyası olduğunda bir şeyler korumak uğruna)

echo "# Whooooo" > /tmp/dummy.sh
for f in '*.pdf'
do
   echo "rm -i $f" >> /tmp/dummy.sh
done

Yukarıdakileri çalıştırdıktan sonra, /tmp/dummy.sh dosyasını fav. düzenleyin ve her bir satırda tehlikeli dosya adları olup olmadığını kontrol edin.

Sonra çalışma dizinine dummy.sh komut dosyasını kopyalayın ve çalıştırın.

Bütün bunlar güvenlik nedeniyle.


5
Sanırım bu örneğin eg-rf .. .pdf
ThiefMaster

evet olurdu, ama genellikle kabukta kullanıldığında, komutun yayıncısı "ne" yaptığına bir göz atmalıdır :). Aslında bir dosyaya yönlendirmeyi ve sonra her bir satırı incelemeyi tercih ederim.
BigMike

2
Bu, "$ f" yi belirtmez. ThiefMaster bunun hakkında konuşuyordu. -rföncelikli -iolduğundan, 2. sürümünüz daha iyi değildir (manuel inceleme olmadan). Ve temelde, her dosyayı sormaktan dolayı toplu silme için işe yaramaz.
Peter Cordes

7

Bir bash dizisi kullanabilirsiniz:

files=(*.pdf)
for((I=0;I<${#files[@]};I+=1000)); do
    rm -f "${files[@]:I:1000}"
done

Bu şekilde adım başına 1000 dosyalık gruplar halinde silinir.


2
Çok sayıda dosya için bu çok daha hızlı görünüyor
James Tocknell


4

Rm komutu aynı anda kaldırabilirsiniz dosyaların bir sınırlama vardır.

Rm komutunu birden çok kez kullanarak dosya desenlerinize dayanarak bunları kaldırabilirsiniz :

rm -f A*.pdf
rm -f B*.pdf
rm -f C*.pdf
...
rm -f *.pdf

Bunları find komutuyla da kaldırabilirsiniz :

find . -name "*.pdf" -exec rm {} \;

3
Hayır, rmişleyeceği dosya sayısı üzerinde böyle bir sınırlama yoktur (bunun argcdışında daha büyük olamaz INT_MAX). Çekirdeğin tüm argüman dizisinin maksimum boyutu üzerindeki sınırlaması budur (bu yüzden dosya adlarının uzunluğu önemlidir).
Toby Speight

3

Boşluklu veya özel karakterli dosya adlarıysa, şunları kullanın:

find -maxdepth 1 -name '*.pdf' -exec rm "{}" \;

Bu cümle, geçerli dizindeki tüm dosyaları (-maxdepth 1) pdf (-name '* .pdf') uzantısıyla arar ve her birini (-exec rm "{}") siler.

{} İfadesi dosyanın adını değiştirir ve "{}" dosya adını boşluklar veya özel karakterler de dahil olmak üzere dize olarak ayarlar.


Bu kod snippet'i, sorunun nasıl ve neden çözüldüğüne dair bir açıklama da dahil olmak üzere soruyu çözebilir, ancak gönderinizin kalitesini artırmaya yardımcı olacaktır . Sadece şu anda soran kişi için değil, gelecekte okuyucular için soruyu cevapladığınızı unutmayın! Lütfen açıklama eklemek için cevabınızı düzenleyin ve hangi sınırlamaların ve varsayımların geçerli olduğunu belirtin.
Toby Speight

Bütün mesele -execbir kabuk çağırmamanızdır. Burada alıntılar kesinlikle yararlı bir şey yapmaz. ( {}
Kabuktaki bu komutta yazdığınız

2

form kaynak dizini hedefe kopyalarken aynı sorunla karşı karşıyaydım

kaynak dizinde ~ 3 lakcs dosyaları vardı

cp seçeneğini -r ile kullandım ve benim için çalıştı

cp -r abc / def /

argüman listesini çok uzun süre uyarmadan abc'den def'e tüm dosyaları kopyalar


Birisi bunun hakkında yorum yapmadan neden bunu düşürdü bilmiyorum (bu politika, millet!). Bir klasör içindeki tüm dosyaları silmem gerekiyordu (soru PDF'ler hakkında özel değil, dikkat edin) ve bunun için bu hile iyi çalışıyor, sonunda yapmanız gereken tek şey, ne zaman boyunca silinen klasörü yeniden oluşturmaktır "Rm -R / path / to / folder" ı kullandım.
Thomas Tempelmann

1
OP'nin durumunda, büyük bir .pdf listesine genişletilmiş * kullanan * kullanıyor, bir dizin vermek bunun dahili olarak ele alınmasına neden olacak, bu nedenle OP'nin sorunuyla uğraşmak zorunda kalmayacaktı. Bence bu nedenle reddedildi.
Dizinde

2

Bunu da deneyin 30/90 günün (+) üzerinde veya 30/90 (-) günlük dosya / klasörlerin altında silmek isterseniz, aşağıdaki ex komutlarını kullanabilirsiniz

Örn: 90 gün boyunca 90 gün boyunca dosya / klasör silindikten sonra hariç tutulur, 91,92 .... 100 gün anlamına gelir

find <path> -type f -mtime +90 -exec rm -rf {} \;

Örn: Yalnızca silmek istediğiniz en son 30 günlük dosyalar için aşağıdaki komutu kullanın (-)

find <path> -type f -mtime -30 -exec rm -rf {} \;

Dosyaları 2 günden fazla gizlemek istiyorsanız

find <path> -type f -mtime +2 -exec gzip {} \;

Dosyaları / klasörleri yalnızca son bir aydan itibaren görmek istiyorsanız. Ör:

find <path> -type f -mtime -30 -exec ls -lrt {} \;

Sadece 30 günden fazla dosya / klasör listeleme Örn:

find <path> -type f -mtime +30 -exec ls -lrt {} \;

find /opt/app/logs -type f -mtime +30 -exec ls -lrt {} \;

2

ulimitBurada cevap olmadığına şaşırdım . Ne zaman bu problemim olursa, buraya veya buraya geliyorum . Bu çözümün sınırlamaları olduğunu anlıyorum ama ulimit -s 65536benim için sık sık hile yapıyor gibi görünüyor.


1

Her gün büyüyen geçici resimlerle dolu bir klasörle aynı sorunu yaşadım ve bu komut klasörü temizlememe yardımcı oldu

find . -name "*.png" -mtime +50 -exec rm {} \;

Diğer komutlardaki fark, yalnızca X günden daha eski dosyaları alacak mtime parametresidir (örnek 50 günde)

Bunu birkaç kez kullanarak, gün aralığındaki her yürütmeyi azaltarak, tüm gereksiz dosyaları kaldırabildim


1

Sadece bunun için bir yol biliyorum. Fikir, sahip olduğunuz pdf dosyaları listesini bir dosyaya aktarmaktır. Sonra bu dosyayı birkaç parçaya bölün. Ardından her bölümde listelenen pdf dosyalarını kaldırın.

ls | grep .pdf > list.txt
wc -l list.txt

wc -l list.txt dosyasının kaç satır içerdiğini saymaktır. Ne kadar uzun olduğu hakkında bir fikriniz olduğunda, onu ikiye, ileriye veya başka bir şeye bölmeye karar verebilirsiniz. Split -l komutunu kullanma Örneğin, her biri 600 satıra bölün.

split -l 600 list.txt

bu xaa, xab, xac adında birkaç dosya oluşturacaktır. Şimdi bu dosyadaki her listeyi rm komutuna "içe aktarmak" için şunu kullanın:

rm $(<xaa)
rm $(<xab)
rm $(<xac)

Kötü ingilizcem için özür dilerim.


5
Eğer adında bir dosya varsa pdf_format_sucks.docxda silinecektir ... ;-) Pdf dosyaları için selamlarken uygun ve doğru düzenli ifade kullanmalısınız.
FooF

1
Daha iyi, ama still_pdf_format_sucks.docxsilinecek. Nokta .içinde ".pdf"düzenli ifade herhangi bir karakterle eşleşir. Bunun "[.]pdf$"yerine önerebilirim .pdf.
FooF

1

Bu problemle birkaç kez karşılaştım. Çözümlerin çoğu, rmsilinmesi gereken her bir dosya için komutu çalıştırır . Bu çok verimsiz:

find . -name "*.pdf" -print0 | xargs -0 rm -rf

Dosya adındaki ilk 4 karaktere göre dosyaları silmek için bir python komut dosyası yazdım:

import os
filedir = '/tmp/' #The directory you wish to run rm on 
filelist = (os.listdir(filedir)) #gets listing of all files in the specified dir
newlist = [] #Makes a blank list named newlist
for i in filelist: 
    if str((i)[:4]) not in newlist: #This makes sure that the elements are unique for newlist
        newlist.append((i)[:4]) #This takes only the first 4 charcters of the folder/filename and appends it to newlist
for i in newlist:
    if 'tmp' in i:  #If statment to look for tmp in the filename/dirname
        print ('Running command rm -rf '+str(filedir)+str(i)+'* : File Count: '+str(len(os.listdir(filedir)))) #Prints the command to be run and a total file count
        os.system('rm -rf '+str(filedir)+str(i)+'*') #Actual shell command
print ('DONE')

Bu benim için çok işe yaradı. Yaklaşık 15 dakika içinde bir klasördeki 2 milyondan fazla geçici dosyayı temizleyebildim. Ben az python bilgisi olan herkes bu kodu manipüle böylece kod biraz dışında tar yorumladı.


1

Ve bir tane daha:

cd  /path/to/pdf
printf "%s\0" *.[Pp][Dd][Ff] | xargs -0 rm

printfbir kabuk yerleşiktir ve bildiğim kadarıyla hep böyle olmuştur. Şimdi verilenprintf bunun bir kabuk komutu değil (bir yerleşik) olduğu , "argument list too long ... ölümcül hataya .

Böylece, kabuk kabartma desenleri ile güvenle kullanabiliriz *.[Pp][Dd][Ff], sonra ( rm) komutunu kaldırmak için çıkışınıxargs , bu da komut satırında başarısız olmamak için komut satırında yeterli dosya adına uyduğundan emin olur.rm , bu da bir kabuk olan komutun komut.

\0İçinde printfo zamana kadar işlenir wich dosya adları için boş ayırıcı olarak sunulduğunda xargsbunu kullanarak komutu ( -0) ayırıcı olarak, yani rmbeyaz boşluk veya dosya adlarında diğer özel karakterler varken başarısız değil.


1
Bu kod snippet'i, sorunun nasıl ve neden çözüldüğüne dair bir açıklama da dahil olmak üzere soruyu çözebilir, ancak gönderinizin kalitesini artırmaya yardımcı olacaktır . Sadece şimdi soran kişi için değil, gelecekte okuyucular için soruyu cevapladığınızı unutmayın! Lütfen açıklama eklemek için cevabınızı düzenleyin ve hangi sınırlamaların ve varsayımların geçerli olduğunu belirtin.
Toby Speight

Özellikle, printfbir kabuk yerleşik değilse, aynı sınırlamaya tabi olacaktır.
Toby Speight

0

Bir geçici klasör oluşturabilir, saklamak istediğiniz tüm dosyaları ve alt klasörleri geçici klasöre taşıyabilir, ardından eski klasörü silebilir ve geçici klasörü eski klasöre yeniden adlandırabilirsiniz.

mkdir testit
cd testit
mkdir big_folder tmp_folder
touch big_folder/file1.pdf
touch big_folder/file2.pdf
mv big_folder/file1,pdf tmp_folder/
rm -r big_folder
mv tmp_folder big_folder

rm -r big_foldertüm dosyaları kaldıracak big_folderkaç olursa olsun. Sadece tutmak istediğiniz tüm dosyalara / klasörlere sahip olduğunuza çok dikkat etmelisiniz, bu durumdafile1.pdf


0

*.pdfBir dizindeki tümünü silmek için/path/to/dir_with_pdf_files/

mkdir empty_dir        # Create temp empty dir

rsync -avh --delete --include '*.pdf' empty_dir/ /path/to/dir_with_pdf_files/

rsyncJoker karakter kullanarak belirli dosyaları silmek , milyonlarca dosyanız olması durumunda en hızlı çözümdür. Ve aldığınız hata ile ilgilenecektir.


(İsteğe bağlı Adım): KURU ÇALIŞTIR. Silmeden nelerin silineceğini kontrol etmek için. '

rsync -avhn --delete --include '*.pdf' empty_dir/ /path/to/dir_with_pdf_files/

. . .

Daha fazla rsync kesmek için rsync ipuçlarını ve püf noktalarını tıklayın


0

Çok büyük dosya listeleri (> 1e6) için bu yanıtların çok yavaş olduğunu gördüm. İşte python'da paralel işleme kullanan bir çözüm. Biliyorum, biliyorum, bu linux deđil ... ama burada baţka hiçbirţey çalýţmadý.

(Bu bana saatler kazandırdı)

# delete files
import os as os
import glob
import multiprocessing as mp

directory = r'your/directory'
os.chdir(directory)


files_names = [i for i in glob.glob('*.{}'.format('pdf'))]

# report errors from pool

def callback_error(result):
    print('error', result)

# delete file using system command
def delete_files(file_name):
     os.system('rm -rf ' + file_name)

pool = mp.Pool(12)  
# or use pool = mp.Pool(mp.cpu_count())


if __name__ == '__main__':
    for file_name in files_names:
        print(file_name)
        pool.apply_async(delete_files,[file_name], error_callback=callback_error)

0

Tüm inode'ları dolduran bir uygulama tarafından oluşturulan milyonlarca işe yaramaz günlük dosyası olduğunda benzer bir sorunla karşılaştım. Ben "bulmak" için başvurdu, tüm dosyaları "bulunan" d bir metin dosyasına aldım ve sonra bunları tek tek kaldırıldı. Bir süre aldı ama işi yaptı!


Bu oldukça belirsiz ve locatehala diskinizde yer olduğunda geri yüklemenizi gerektirir .
tripleee

-2

Xargs kullanmaktan biraz daha güvenli bir sürüm, özyinelemeli değil: ls -p | grep -v '/$' | grep '\.pdf$' | while read file; do rm "$file"; done

Buradaki dizinlerimizi filtrelemek biraz gereksiz çünkü 'rm' onu silmeyecek ve basitlik için kaldırılabilir, ancak neden kesinlikle hata döndürecek bir şey çalıştırıyorsunuz?


3
Bu hiç de güvenli değildir ve belirgin bir köşe örneğini belirtmek için içinde yeni satırları olan dosya adları ile çalışmaz. Ayrıştırmals , kesinlikle kaçınılması gereken ve burada bir takım ek hatalar ekleyen yaygın bir antipatterndir. grep | grepSadece çok şık değil.
Üçlü

Her neyse, bu karmaşık bir çözüm gerektiren yeni ve egzotik bir sorun gibi değil. İle cevaplar findiyi ve burada ve başka yerlerde iyi belgelenmiş. Bu ve ilgili konular hakkında daha fazla bilgi için örneğin mywiki.wooledge.org adresine bakın .
Üçlü

-2

GNU parallel ( sudo apt install parallel) kullanmak çok kolay

'{}' İletilen argüman olan çoklu iş parçacıklı komutları çalıştırır

Örneğin

ls /tmp/myfiles* | parallel 'rm {}'


Bilmiyorum, ama sanırım bunun lssonucunu doğrudan diğer komutlara geçirmek tehlikeli bir antipattern - ve joker karakterin genişlemesinin lsorijinal rmkomutta deneyimlendiği gibi aynı başarısızlığa neden olması gerçeği .
Toby Speight

Bu bağlam için bkz ParsingLs . Ve parallelkarmaşıklıktan kaçınmayı tercih eden bazı insanları rahatsız eder - kaputun altına bakarsanız, oldukça opaktır. Stephane ( Unix ve Linux StackExchange greybeards'ından biri) ve Ole Tange (Parallel'in yazarı) arasındaki lists.gnu.org/archive/html/bug-parallel/2015-05/msg00005.html adresindeki posta listesi iş parçacığına bakın . aynı zamanda paralellize olur, ancak daha az hareketli parça ile daha basit, daha düzgün bir şekilde yapar, davranışını tahmin etmeyi ve akıl yürütmeyi çok daha kolay hale getirir. xargs -P
Charles Duffy

-2

İlk 100 dosyayı kaldırmak için:

rm -rf 'ls | kafa -100 '


2
Tehlikeli (veya açık bir şekilde öngörülen şekilde tırnak işaretleri kullanırsanız olurdu) - herhangi bir dosya adı boşluklar da dahil olmak üzere kabuk metakarakterleri içeriyorsa, sonuçlar istediğiniz gibi olmaz.
Toby Speight

-5

Aşağıdaki seçenek bu sorun için basit görünüyor. Bu bilgiyi başka bir iş parçacığından aldım ama bana yardımcı oldu.

for file in /usr/op/data/Software/temp/application/openpages-storage/*; do
    cp "$file" /opt/sw/op-storage/
done

Yukarıdaki komutlardan birini çalıştırmanız yeterlidir.

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.