Script para manter diretórios específicos que contenham um arquivo .txt e exclua os arquivos dos outros diretórios sem o arquivo .txt específico [closed]

0

Estou quase terminando o script, mas isso gera diretórios. O que eu gostaria é ter uma saída de arquivos. De qualquer forma um de vocês quer me ajudar? :)

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

A saída é:

/testftp/logs

A saída é o diretório de onde DONOTDELETE.TXT não existe. Está bem perto. Só precisa exibir os arquivos.

    
por JoyIan Yee-Hernandez 24.02.2012 / 18:18

3 respostas

1

Aqui está minha opinião sobre isso:

#! /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

Adicione isso a um script, modifique as variáveis com sua própria convenção de nomenclatura, se desejar (para o arquivo especial e o nome do log), e, em seguida, chame-o apenas com o caminho do diretório inicial como um parâmetro. Ele excluirá qualquer diretório que contenha o arquivo desejado e excluirá todo o resto.

    
por 25.02.2012 / 06:00
1

Pensei em dar uma chance a esta pessoa.


#!/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

    
por 24.02.2012 / 21:27
0

Se você tiver 4 + bash (confira com bash --version ), você pode fazer isso em um de dois-liner:

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

Note que shopt -s globstar precisa estar em sua própria linha - não apenas prefixá-lo no loop for com um ; .

./**/ expande para cada subdiretório no diretório atual e seus subdiretórios recursivamente. Se você quiser apenas descer a árvore em um único nível, use ./*/ (e não se preocupe em configurar globstar); Se você quiser um controle melhor do que isso, terá que mexer com find (especificamente as opções -maxdepth e -mindepth ). Eu uso ./**/ em vez de **/ no caso de qualquer um de seus diretórios começar com - : isso os impede de serem vistos como

[[ -f "$f"/DONOTDELETE.TXT ]] testa se esse arquivo existe e é um arquivo (se você quiser que ele funcione mesmo que DONOTDELETE.TXT possa ser algo diferente de um arquivo, use -e em vez de -f ). Estritamente falando, você não precisa do / lá, já que $ f contém uma barra final, mas acho que fica melhor assim, e em geral as barras redundantes são inofensivas. || significa OR - se (e somente se) o teste for avaliado como falso , o código à direita será executado, neste caso rm -f "$f"/* - que exclui todos os arquivos, exceto os escondidos.

Se você quiser excluir arquivos ocultos também, use algo como:

for f in ./**/; do [[ -f "$f"/DONOTDELETE.TXT ]] || rm -f "$f"/* "$f"/.*; done
    
por 28.05.2013 / 12:33