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.

JoyIan Yee-Hernandez
la source
(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.

Yanick Girouard
la source
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

tao
la source
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
evilsoup
la source