Encontre todos os arquivos com o mesmo nome

0

Eu tenho muitos arquivos com o mesmo nome em pastas diferentes. Como posso encontrar todos os caminhos e escrevê-los em um arquivo de texto?

    
por aortizma 12.09.2018 / 09:33

5 respostas

2

Eu usaria find . Assim:

find <path> -type f -name <filename> > same_name.txt

Exemplo:

find . -type f -name "foo" > same_name.txt
cat same_name.txt 
./dir_a/foo
./foo
./dir_b/foo
./tmp/foo

Os itens acima encontram todos os arquivos recursivamente, começando pelo diretório atual, com o nome foo . O resultado é salvo no arquivo same_name.txt

    
por 12.09.2018 / 10:06
0

Se instalado, você pode usar locate .

locate filename

ou salve em um arquivo:

locate filename > same_name.txt

Para pesquisar em um determinado local, somente você pode filtrar os resultados usando o grep:

locate filename | grep "/path/"
# e.g. search only in your /home folder
locate filename | grep "$HOME"

Nota:

  • locate é muito mais rápido que find , porque realiza uma pesquisa de banco de dados em uma varredura de uma vez por dia no seu disco rígido.
  • Não encontrará ficheiros adicionados hoje.
  • Ele não localizará arquivos em determinados caminhos ou sistemas de arquivos e montagens (execute cat /etc/updatedb.conf para ver o que é excluído).
por 12.09.2018 / 10:25
0

Aqui está um script completo (eu chamei-o de find-double-names.sh ) que encontra todos os nomes de arquivos que ocorrem mais de uma vez. Se você está fazendo isso para limpar, lembre-se de que arquivos com o mesmo nome podem ter conteúdo diferente.

Por exemplo para encontrar todos os nomes de arquivos duplos em seu diretório home, execute-o assim:

find-double-names.sh $HOME

Você pode passar mais diretórios para incluir na pesquisa, por exemplo:

find-double-names.sh $HOME /usr/local /var/tmp

Quando você tem muitos arquivos, obviamente esse script pode levar algum tempo para ser executado e também requer algum espaço em disco em / tmp.

#!/bin/bash

# This is the name of this script itself.
#
script="${0##*/}"

# The  arguments passed to this script are the parent
# directories to be searched, e.g: /home/me /usr/local
# Check if any given. If not, error out.
#
if [ -z "$1" ] ; then
    echo "Usage: $script <directory> [<directory>][...]" >&2
    exit 1
fi

# Create a temporary directory. For accurate results we need
# to be sure it is empty. This is one way to do this: create
# an temp dir that is garanteed to not exist yet.
#
# If you want to keep the "outputdir" with the results, make sure
# output dir you use does not contain files you want to keep, because
# files will be removed from it by this script! Better yet, make
# sure it is empty before starting this script.
#
outputdir=$(mktemp --tmpdir -d "${script}.XXXXXXXXXX")   # ensures new unique directory
trap "rm -r $outputdir" INT HUP QUIT ABRT ALRM TERM EXIT # ensures it is deleted when script ends

# Search the directories given as arguments, and process
# the paths of alle files one by one in a loop.
#
find "$@" -type f | while read path ; do
    filename="${path##*/}"
    echo "$path" >>"${outputdir}/${filename}.txt"
done

# Finally, if you want to end up with only file names that
# occur more than once, delete all output files that contain
# only one line.
#
for outputfile in $outputdir/*.txt ; do
    linecount=$(wc -l "$outputfile" | sed 's/ .*//')  # count lines in it
    if  [ "$linecount" = "1" ] ; then                 # if only one line
        rm "$outputfile"                              # remove the file
    fi
done

# Print the final result
#
for outputfile in $outputdir/*.txt ; do
    cat "$outputfile"
    echo               # empty line to separate groups of same file names
done
    
por 12.09.2018 / 10:43
0

O seguinte script bash recursivamente localiza todos os nomes de arquivos regulares (ou links simbólicos para arquivos regulares) que são duplicados no caminho de nível superior dado na linha de comando para o script (ou no diretório atual, se não houver caminho é dado).

No final, um resumo de cada nome de arquivo duplicado é fornecido com uma lista de nomes de diretório : -delimited, onde o nome do arquivo pode ser encontrado.

#!/bin/bash

shopt -s globstar  # enable the ** glob
shopt -s dotglob   # also let patterns match hidden files

declare -A dirs    # where we store directories for each found name

for pathname in "${1:-.}"/**; do
    [ ! -f "$pathname" ] && continue  # not something we're interested in

    name=${pathname##*/}
    if [ -n "${dirs[$name]}" ]; then
        # we have seen this filename before
        dups+=( "$name" )
    fi

    # append directory name to ':'-delimited list for this filename
    dirs[$name]=${dirs[$name]:+"${dirs[$name]}:"}"${pathname%/*}"
done

# go through the list of duplicates and 
# print the found directory names for each
for name in "${dups[@]}"; do
    printf '%s:\n\t%s\n' "$name" "${dirs[$name]}"
done

Exemplo de execução:

$ bash script.sh
somefile:
        ./a:./b
.profile:
        .:./t

O resumo nos diz que .profile é encontrado no diretório atual, bem como no diretório t , e que somefile é encontrado nos diretórios a e b .

    
por 12.09.2018 / 11:35
0

Isso tratará do caso geral em que você sabe que há nomes de arquivo duplicados, mas não sabe o que são:

find -type f -print0 |
    awk -F/ 'BEGIN { RS="
# Preparation
mkdir -p tmp/a tmp/b
touch tmp/a/xx tmp/a/yy tmp/b/yy tmp/b/zz

# Do it
find tmp -type f -print0 |
    awk -F/ 'BEGIN { RS="
find -type f -print0 |
    awk -F/ 'BEGIN { RS="
# Preparation
mkdir -p tmp/a tmp/b
touch tmp/a/xx tmp/a/yy tmp/b/yy tmp/b/zz

# Do it
find tmp -type f -print0 |
    awk -F/ 'BEGIN { RS="%pre%" } { n=$NF } k[n]==1 { print p[n]; } k[n] { print $0 } { p[n]=$0; k[n]++ }'

tmp/a/yy
tmp/b/yy

# Tidyup
rm -rf tmp
" } { n=$NF } k[n]==1 { print p[n]; } k[n] { print $0 } { p[n]=$0; k[n]++ }'
" } { n=$NF } k[n]==1 { print p[n]; } k[n] { print $0 } { p[n]=$0; k[n]++ }' tmp/a/yy tmp/b/yy # Tidyup rm -rf tmp
" } { n=$NF } k[n]==1 { print p[n]; } k[n] { print $0 } { p[n]=$0; k[n]++ }'

Dentro do script awk , lidamos com caminhos de arquivo que são terminados por NULL (para que possamos processar nomes de arquivos que possam conter novas linhas), com $0 como o nome de caminho do arquivo atual. A variável n contém o componente do nome do arquivo. k[] é um hash (codificado por n ) que conta o número de ocorrências desse nome de arquivo e p[] é outro hash (também digitado por n ) que contém o primeiro nome de caminho completo correspondente.

Exemplo

%pre%     
por 12.09.2018 / 11:05

Tags