Als ik sudo rm -r
gebruik, hoe kan ik dan alle bestanden verwijderen, met uitzondering van het volgende:
textfile.txt
backup.tar.gz
script.php
database.sql
info.txt
Antwoord 1, autoriteit 100%
find [path] -type f -not -name 'textfile.txt' -not -name 'backup.tar.gz' -delete
Als u -type f
niet opgeeft, zal find ook mappen weergeven, wat u misschien niet wilt.
Of een meer algemene oplossing met behulp van de zeer handige combinatie find | xargs
:
find [path] -type f -not -name 'EXPR' -print0 | xargs -0 rm --
verwijder bijvoorbeeld alle niet-txt-bestanden in de huidige map:
find . -type f -not -name '*txt' -print0 | xargs -0 rm --
De combinatie print0
en -0
is nodig als er spaties zijn in een van de bestandsnamen die moeten worden verwijderd.
Antwoord 2, autoriteit 68%
rm !(textfile.txt|backup.tar.gz|script.php|database.sql|info.txt)
De extglob (Extended Pattern Matching) moet worden ingeschakeld in BASH (als deze niet is ingeschakeld):
shopt -s extglob
Antwoord 3, autoriteit 18%
find . | grep -v "excluded files criteria" | xargs rm
Hiermee worden alle bestanden in de huidige map weergegeven, vervolgens worden alle bestanden weergegeven die niet aan uw criteria voldoen (pas op dat deze overeenkomen met mapnamen) en worden ze vervolgens verwijderd.
Update: als je op basis van je bewerking echt alles uit de huidige map wilt verwijderen, behalve de bestanden die je hebt vermeld, kan dit worden gebruikt:
mkdir /tmp_backup && mv textfile.txt backup.tar.gz script.php database.sql info.txt /tmp_backup/ && rm -r && mv /tmp_backup/* . && rmdir /tmp_backup
Het zal een back-upmap maken /tmp_backup
(je hebt root-rechten, toch?), bestanden die je hebt vermeld naar die map verplaatsen, recursief alles in de huidige map verwijderen (je weet dat je’ opnieuw in de juiste map, nietwaar?), ga terug naar de huidige map alles van /tmp_backup
en verwijder ten slotte /tmp_backup
.
Ik kies de back-upmap in root, want als je probeert om alles recursief uit root te verwijderen, zal je systeem grote problemen hebben.
Er zijn zeker elegantere manieren om dit te doen, maar deze is vrij eenvoudig.
Antwoord 4, autoriteit 10%
Ik gebruik liever een subquerylijst:
rm -r `ls | grep -v "textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt"`
-v, –invert-match selecteer niet-overeenkomende regels
\|
Scheidingsteken
Antwoord 5, autoriteit 9%
Ervan uitgaande dat bestanden met die namen op meerdere plaatsen in de directorystructuur voorkomen en u ze allemaal wilt behouden:
find . -type f ! -regex ".*/\(textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt\)" -delete
Antwoord 6, autoriteit 8%
Je kunt de GLOBIGNORE-omgevingsvariabele gebruiken in Bash.
Stel dat je alle bestanden wilt verwijderen behalve php en sql, dan kun je het volgende doen –
export GLOBIGNORE=*.php:*.sql
rm *
export GLOBIGNORE=
Als u GLOBIGNORE op deze manier instelt, worden php en sql genegeerd van jokertekens die worden gebruikt zoals “ls *” of “rm *”. Dus als u “rm *” gebruikt na het instellen van de variabele, worden alleen het txt- en tar.gz-bestand verwijderd.
Antwoord 7, autoriteit 4%
Omdat niemand het noemde:
- Kopieer de bestanden die u niet wilt verwijderen op een veilige plaats
- verwijder alle bestanden
- verplaats de gekopieerde bestanden terug
Antwoord 8, autoriteit 3%
Je kunt hiervoor een for-lus schrijven… %)
for x in *
do
if [ "$x" != "exclude_criteria" ]
then
rm -f $x;
fi
done;
Antwoord 9, autoriteit 3%
Een beetje laat voor de OP, maar hopelijk nuttig voor iedereen die hier veel later komt via google…
Ik vond het antwoord van @awi en commentaar op -delete van @Jamie Bullock erg nuttig. Een eenvoudig hulpprogramma zodat u dit in verschillende mappen kunt doen, waarbij u elke keer verschillende bestandsnamen/typen negeert met minimaal typen:
rm_behalve (of hoe je het ook wilt noemen)
#!/bin/bash
ignore=""
for fignore in "[email protected]"; do
ignore=${ignore}"-not -name ${fignore} "
done
find . -type f $ignore -delete
bijv. om alles te verwijderen behalve tekstbestanden en foo.bar:
rm_except *.txt foo.bar
Vergelijkbaar met @mishunika, maar zonder de if-clausule.
Antwoord 10, autoriteit 2%
Als je zsh
gebruikt, wat ik ten zeerste aanbeveel.
rm -rf ^file/folder pattern to avoid
Met extended_glob
setopt extended_glob
rm -- ^*.txt
rm -- ^*.(sql|txt)
Antwoord 11, autoriteit 2%
Proberen werkte met:
rm -r !(Applications|"Virtualbox VMs"|Downloads|Documents|Desktop|Public)
maar namen met spaties zijn (zoals altijd) moeilijk. Ook geprobeerd met Virtualbox\ VMs
in plaats van de aanhalingstekens. Het verwijdert altijd die map (Virtualbox VMs
).
Antwoord 12, autoriteit 2%
Gewoon:
rm $(ls -I "*.txt" ) #Deletes file type except *.txt
Of:
rm $(ls -I "*.txt" -I "*.pdf" ) #Deletes file types except *.txt & *.pdf
Antwoord 13
Maak de bestanden onveranderlijk. Zelfs root mag ze niet verwijderen.
chattr +i textfile.txt backup.tar.gz script.php database.sql info.txt
rm *
Alle andere bestanden zijn verwijderd.
Uiteindelijk kun je ze veranderlijk resetten.
chattr -i *
Antwoord 14
Ik geloof dat je kunt gebruiken
rm -v !(filename)
Behalve de bestandsnaam worden alle andere bestanden in de map verwijderd en zorg ervoor dat u deze gebruikt in
Antwoord 15
Dit is vergelijkbaar met de opmerking van @siwei-shen, maar je hebt de vlag -o
nodig om meerdere patronen te maken. De vlag -o
staat voor ‘of’
find . -type f -not -name '*ignore1' -o -not -name '*ignore2' | xargs rm
Antwoord 16
U kunt dit doen met twee opdrachtreeksen.
Definieer eerst een array met de naam van de bestanden die u niet wilt uitsluiten:
files=( backup.tar.gz script.php database.sql info.txt )
Loop daarna door alle bestanden in de map die u wilt uitsluiten, controleer of de bestandsnaam in de array staat die u niet wilt uitsluiten; zo niet, verwijder dan het bestand.
for file in *; do
if [[ ! " ${files[@]} " ~= "$file" ]];then
rm "$file"
fi
done
Antwoord 17
Omdat nog niemand dit heeft genoemd, in één specifiek geval:
OLD_FILES=`echo *`
... create new files ...
rm -r $OLD_FILES
(of gewoon rm $OLD_FILES
)
of
OLD_FILES=`ls *`
... create new files ...
rm -r $OLD_FILES
Misschien moet je shopt -s nullglob
gebruiken als sommige bestanden er wel of niet zijn:
SET_OLD_NULLGLOB=`shopt -p nullglob`
shopt -s nullglob
FILES=`echo *.sh *.bash`
$SET_OLD_NULLGLOB
zonder nullglob, echo *.sh *.bash
kan je “a.sh b.sh *.bash” geven.
(Dat gezegd hebbende, geef ik zelf de voorkeur aan dit antwoord, ook al werkt het niet in OSX)
Antwoord 18
In plaats van een direct commando te gebruiken, verplaats de vereiste bestanden naar de tijdelijke map buiten de huidige map. Verwijder vervolgens alle bestanden met rm *
of rm -r *
.
Verplaats vervolgens de vereiste bestanden naar de huidige map.
Antwoord 19
Verwijder alles behalve bestandsnaam:
ls -d /path/to/your/files/* |grep -v file.name|xargs rm -rf