Script permettant de conserver des répertoires spécifiques contenant un fichier .txt et de supprimer les fichiers des autres répertoires sans le fichier .txt spécifique [fermé]


0

J'en ai presque fini avec le script mais cela génère des répertoires. Ce que j'aimerais, c'est avoir une sortie de fichiers. Quoi qu'il en soit, l'un de vous veut m'aider? :)

    #!bin/bash
( find /testftp/* -type d ;
  find /testftp/* -type f -iname DONOTDELETE.TXT -printf '%h'
) | sort | uniq -u

La sortie est:

/testftp/logs

La sortie est le répertoire où DONOTDELETE.TXT n’existe pas. C'est assez proche. Juste besoin d'afficher les fichiers.


(1) Vous voulez supprimer fichiers seulement dans un répertoire qui n'a pas NE PAS SUPPRIMER.TEXT, mais pas le répertoire lui-même? (2) Quel ensemble de répertoires le printf affiche-t-il maintenant? Ceux avec le fichier TXT ou ceux sans ce fichier?
ADTC

(1) oui! (2) printf affiche le répertoire où DONOTDELETE.TXT N'EXISTE PAS. MAIS il affiche également "/ testftp" qui est le répertoire contenant les autres sous-répertoires. Donc c'est assez proche mais je perds maintenant LOL
JoyIan Yee-Hernandez

Essayer -exec list {}/* au lieu de -printf '%h'. S'il montre les bons fichiers seulement peut-être que vous pouvez essayer -exec rm -f {}/* ( Attention: c'est dangereux! ). En outre, cela peut être utile.
ADTC

Avec ce code ( find /testftp -type d ; find /testftp -type f -iname DONOTDELETE.TXT -exec list {} \; ) | sort | uniq -u La sortie est: `find: list: Aucun fichier ou répertoire de ce type / testftp / testftp / logger / testftp / logs` DONOTDELETE.TXT est sous `/ testftp / logger`
JoyIan Yee-Hernandez

Désolé, ça aurait dû être ls ne pas list (oublie toujours ça!)
ADTC

Réponses:


1

Voici mon point de vue sur elle:

#! /bin/bash

SPECIAL_FILE=DONOTDELETE
LOGFILE=clean.$(date +"%Y-%d-%m.%H%M%S").log   
FIND_BASE="$1"
if [ $# -ne 1 ]; then
        echo "Syntax $(basename $0) <FIND_BASE>"
        exit 1
fi
if [ "$FIND_BASE" = "." ]; then
        FIND_BASE=$(pwd)
else
        FIND_BASE=$(pwd)/$FIND_BASE
fi

for d in $(find $FIND_BASE -type d -print); do
        if [ "$d" != "$FIND_BASE" ]; then
                ls $d | grep $SPECIAL_FILE &> /dev/null
                if [ $? -ne 0 ]; then
                        echo "Deleting $d" | tee -a $LOGFILE
                        rm -rf $d 2>/dev/null
                else
                        echo "Ignoring $d, contains $SPECIAL_FILE" | tee -a $LOGFILE
                fi
        fi
done
exit 0

Ajoutez ceci à un script, modifiez les variables avec votre propre convention de dénomination si vous le souhaitez (pour le fichier spécial et le nom du journal), puis appelez-le simplement avec le chemin du répertoire de départ en tant que paramètre. Il exclura tout répertoire contenant le fichier souhaité et supprimera tout le reste.


1

Je pensais que j'essaierais celui-ci.


#!/bin/bash
# file name and path can not have spaces for this to work.

ignorefile=DONOTDELETE.TXT
dir="`find /testftp/* -type d`";
exists=$(ls $dir | for each in $(find $dir -type f -iname $ignorefile -printf '%h\n'); do echo -en "grep -v $each |" ; done | sed '$s/.$//') 
direxists=$(ls $dir | eval $exists | grep -v $ignorefile | sed 's/:/\//g' | sort | uniq -u)

for pth in $direxists; 
do 
if [ -d $pth ]; then 
if [ "$(ls -A $pth)" ]; then 
echo rm -f ""$pth*""
fi
fi
done

reproduce:
changed dir="`find /testftp/* -type d`";
to
dir="`find ./testftp/* -type d`";

mkdir testftp && cd testftp
for x in 1 2 3 4 5 6 7 8 9; do mkdir $x; done
for y in 1 2 3 4 6 7 9; do touch $y/blah; done
touch 5/DONOTDELETE.TXT
touch 5/some.log
touch 8/DONOTDELETE.TXT
touch 8/another.file

cd ..
$ ./script.sh 
rm -f ./testftp/1/blah
rm -f ./testftp/2/blah
rm -f ./testftp/3/blah
rm -f ./testftp/4/blah
rm -f ./testftp/6/blah
rm -f ./testftp/7/blah
rm -f ./testftp/9/blah


J'ai essayé ça. `#! / bin / bash # le nom de fichier et le chemin ne peuvent pas avoir d'espaces pour que cela fonctionne. ignorefile = DONOTDELETE.TXT dir = " find ./testftp/* -type d "; existe = $ (ls $ dir | pour chacun dans $ (trouver $ dir -type f -iname $ ignorefile -printf '% h \ n'); ne echo -en" grep -v $ each | "; done | sed '$ s /.$//') direxists = $ (ls $ dir | eval $ existe | grep -v $ ignorefile | sed 's /: / \ // //' | sort | uniq -u) pour pth in $ direxists; do si [-d $ pth]; alors si ["$ (ls -A $ pth)"]; alors echo rm -f "" $ pth * "" fi fi done `Mais il n'a rien fait :(
JoyIan Yee-Hernandez

Des pensées? :)
JoyIan Yee-Hernandez

Ce que vous avez collé ici et ce que j'ai mis en place sont au nombre de deux. et si vous utilisez cygwin / windows, oubliez-le
tao

0

Si vous avez bash 4+ (vérifiez auprès de bash --version ), vous pouvez le faire dans une ligne double:

shopt -s globstar
for f in ./**/; do [[ -f "$f"/DONOTDELETE.TXT ]] || rm -f "$f"/*; done

Notez que shopt -s globstar doit être sur sa propre ligne - ne pas simplement l'ajouter à la boucle avec un ;.

./**/ étend à chaque sous-répertoire dans le répertoire en cours et leurs sous-répertoires de manière récursive. Si vous voulez seulement descendre d’un arbre à l’autre, utilisez ./*/ au lieu de cela (et ne vous inquiétez pas de mettre globstar); si vous voulez un contrôle plus fin que cela, vous devrez jouer avec find à la place (en particulier le -maxdepth et -mindepth options). j'utilise ./**/ au lieu de **/ au cas où l'un de vos répertoires commence par un -: cela les empêche d'être vu comme

[[ -f "$f"/DONOTDELETE.TXT ]] teste pour voir si ce fichier existe et est un fichier (si vous voulez qu'il fonctionne même si DO NOT DELETE.TEXT peut être autre chose qu'un fichier, utilisez -e au lieu de -f ). Strictement parlant, vous n'avez pas besoin de / dedans, puisque $ f contient une barre oblique de fin, mais je pense que cela a l'air mieux ainsi, et en général les barres obliques redondantes sont inoffensives. || signifie OU - si (et seulement si) ce test a pour résultat faux , alors le code à droite de celui-ci sera exécuté, dans ce cas rm -f "$f"/* - qui supprime tous les fichiers, sauf les fichiers cachés.

Si vous souhaitez également supprimer des fichiers cachés, vous pouvez utiliser quelque chose comme:

for f in ./**/; do [[ -f "$f"/DONOTDELETE.TXT ]] || rm -f "$f"/* "$f"/.*; done
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.