Bir metin dosyasında listelenen dosyalar nasıl silinir


23

Çeşitli dosyalara giden yolların listesini içeren bir metin dosyasına sahibim. Her satır boyunca yinelenen ve belirtilen yolda dosyayı silen kullanabileceğim bir komut var mı?

Yanıtlar:


33

Kullanım xargs:

xargs rm < file  # or
xargs -a file rm

Ancak, dosya adları / yolları, kaçması gereken karakterler içeriyorsa işe yaramaz.

Dosya adlarınız yeni satırlara sahip değilse, şunları yapabilirsiniz:

tr '\n' '\0' < file | xargs -0 rm # or
xargs -a file -I{} rm {}

Alternatif olarak, aşağıdaki betiği oluşturabilirsiniz:

#!/bin/bash

if [ -z "$1" ]; then
    echo -e "Usage: $(basename $0) FILE\n"
    exit 1
fi

if [ ! -e "$1" ]; then
    echo -e "$1: File doesn't exist.\n"
    exit 1
fi

while read -r line; do
    [ -n "$line" ] && rm -- "$line"
done < "$1"

Farklı kaydet /usr/local/bin/delete-from, yürütme izni ver:

sudo chmod +x /usr/local/bin/delete-from

Ardından ile çalıştırın:

delete-from /path/to/file/with/list/of/files

2
Gerçekten temiz cevap, ama catgerekli değil, stdinyönlendirme kullanabilirsiniz :< file xargs rm
kos

Klasörlerin bölme isimleri yukarı ve sonra onları arıyorum. Mesela MY FOLDER "MY" ve "FOLDER" olarak yorumlanıyor mu?
daka

@sudoman Cevap güncellendi.
Eric Carvalho

Dosyalarda boşluk yoksa, bash'da sadece "rm - $ (cat dosyası)" veya cat file(ba) sh veya csh içinde "rm - " kullanabilirsiniz.
shooper

@shooper faydasız cat, az önce de belirtildiği gibi faydalanın stdin! Güncellenmiş cevabına bak
kos

20

İşte beyaz boşluk, ters eğik çizgi ve diğer garip karakterlerle dosya adlarıyla başa çıkmanın bir yolu:

while read -r file; do rm -- "$file"; done < list.txt

Bu, her satırını okuyacak list.txt, kaydedin $fileve rmüzerinde çalışacaktır . -r(Böylece ters eğik çizgiler anlamıyla okumak edilmesini sağlar \tbir eşleşir \ve tve bir TAB). Aynı --zamanda başlayan dosya adlarıyla da ilgilenmesini sağlar -.

Bunu Perl'de de yapabilirsiniz:

perl -lne '$k{$_}++; END{unlink for keys(%k)}' list.txt

Bu, her dosya adını %kkarma içine okur ve ardından unlinkher birini silmek için kullanır .


10

Python aracılığıyla.

import sys
import os
fil = sys.argv[1]
with open(fil) as f:
    for line in f:
        os.remove(line.rstrip('\n'))

Yukarıdaki betiği, like adlı bir dosyaya kaydedin script.pyve sonra betiği terminalde çalıştırarak betiği çalıştırın.

python3 script.py file

file gerçekte kaldırmak istediğiniz dosyaların yolunun depolandığı bir giriş dosyasıdır.


6
Ah, en azından bir python cevabı gönderecek cesaretin var :)
Jacob Vlijm 14:15

3

Aptal, ama işte biri:

 tar -cvf /dev/null --remove-files -T filename

2

Bunu yapmanın başka bir yolu:

Dosyayı bir kabuk betiği yaparak 'hazırlayabilirsiniz':

$ sed -E "s/^(.*)$/rm '\1'/" input_file
rm 'file1'
rm 'file2'
rm 'file with some spaces.ext'

Eğer dosya isimleriniz tek bir alıntıya ( ') sahipse, önce bunlardan kaçmak için bu biraz genişletilmiş versiyonu kullanabilirsiniz:

$ sed -E "s/'/'\\\''; s/^(.*)$/rm '\1'/" input_file
rm 'file1'
rm 'file2'
rm 'file with some spaces.ext'
rm 'a file with "quotes"'
rm 'a file with '\''quotes'\'''

Ve bunu şu şekilde çalıştırarak çalıştırabilirsiniz sh:

$ sed -E "s/'/'\\\''; s/^(.*)$/rm '\1'/" input_file | sh

1

Anladığım kadarıyla, tüm yolları olan dosyalarla bir metin dosyanız var. İki olasılık var:

  1. Listenizin dosya adları yeni satırlarla ayrılmış, yani her satırda bir dosyanın tam yolu vardır. bu durumda: işte basit bir çıkış yolu:

    for i in $(cat listOfFiles.txt); do
        rm -f $i
    done
    
  2. Listenizde boşluklar veya sekmelerle ayrılmış bir veya daha fazla dosya adı satırı varsa, işte detaylar:

    sed -i 's/\s\+/\n/g' listOfFiles.txt
    

    bu, tüm boşlukları newlines'a dönüştürür

    for i in $(cat listOfFiles.txt); do
        rm -f $i
    done
    

Evet, bunu yapmanın birçok yolu var, ama bu çok basit bir yaklaşım.

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.