Enumerar archivos recursivamente en la CLI de Linux con la ruta relativa al directorio actual

224

Esto es similar a esta pregunta , pero quiero incluir la ruta relativa al directorio actual en Unix. Si hago lo siguiente:

ls -LR | grep .txt

No incluye los caminos completos. Por ejemplo, tengo la siguiente estructura de directorios:

test1/file.txt
test2/file1.txt
test2/file2.txt

El código anterior devolverá:

file.txt
file1.txt
file2.txt

¿Cómo puedo hacer que incluya las rutas relativas al directorio actual usando los comandos estándar de Unix?

Darryl Hein
fuente
44
Esto solo muestra que a ls le falta esta característica.
Arjun Singri
1
Es una pena que todas estas soluciones requieran findo tree. Me estoy metiendo en un dispositivo Android donde parece que solo tengo ls, y ninguna de estas otras herramientas: /
Ponkadoodle

Respuestas:

304

Use buscar:

find . -name \*.txt -print

En los sistemas que usan GNU find, como la mayoría de las distribuciones de GNU / Linux, puede omitir la impresión.

Andru Luvisi
fuente
11
... y para el caso, puede omitir el '.'
Adam Mitz
77
Para rutas absolutas, usefind $(pwd) -name \*.txt
Zags
2
Si el patrón tiene parte del nombre del directorio, debe usarlo en -path "*docs/*.txt"lugar de -name. -wholenamees lo mismo que-path
guiones
99
Úselo -type fsolo para devolver archivos y no directorios, enlaces simbólicos, etc.
usuario
2
-name "*.txt"se NO coincidir file.TXT- utilizar siempre -iname "*.txt"en su lugar, que es sensible a las mayúsculas.
ccpizza
73

Uso tree, con -f(ruta completa) y -i(sin líneas de sangría):

tree -if --noreport .
tree -if --noreport directory/

Luego puede usar greppara filtrar los que desee.


Si no se encuentra el comando, puede instalarlo:

Escriba el siguiente comando para instalar el comando de árbol en RHEL / CentOS y Fedora Linux:

# yum install tree -y

Si está utilizando Debian / Ubuntu, Mint Linux escriba el siguiente comando en su terminal:

$ sudo apt-get install tree -y
Stephen Irons
fuente
2
¿alguna configuración para enumerar solo los archivos y excluir carpetas?
thebugfinder
25

Tratar find. Puede buscarlo exactamente en la página de manual, pero es así:

find [start directory] -name [what to find]

entonces para tu ejemplo

find . -name "*.txt"

debería darte lo que quieres.

Jonathan Adelson
fuente
9

Puedes usar find en su lugar:

find . -name '*.txt'
Sherm Pendley
fuente
5

Eso hace el truco:

ls -R1 $PWD | while read l; do case $l in *:) d=${l%:};; "") d=;; *) echo "$d/$l";; esac; done | grep -i ".txt"

Pero lo hace al "pecar" con el análisis de ls, sin embargo, lo que las comunidades GNU y Ghostscript consideran una mala forma.

El Guesto
fuente
2
@CAFEBABE: se considera tabú analizar los resultados lsporque generalmente genera errores. La oración en cuestión estaba tratando de decir eso. También tenía una broma que eliminé.
Adam Katz
4
DIR=your_path
find $DIR | sed 's:""$DIR""::'

'sed' borrará 'your_path' de todos los resultados 'find'. Y recibes en relación con la ruta 'DIR'.

h-dima
fuente
¿Esto es exactamente lo que necesito pero todavía me escupe todo el camino?
v3nt
1
no use el apóstrofe - find / tmp | sed s: "/ tmp" :: | más
Kieren Dixon
4

Para obtener los nombres de archivo de ruta completa de los archivos deseados utilizando el comando find, úselo con el comando pwd:

find $(pwd) -name \*.txt -print
ZaSter
fuente
1

Aquí hay un script de Perl:

sub format_lines($)
{
    my $refonlines = shift;
    my @lines = @{$refonlines};
    my $tmppath = "-";

    foreach (@lines)
    {
        next if ($_ =~ /^\s+/);
        if ($_ =~ /(^\w+(\/\w*)*):/)
        {
            $tmppath = $1 if defined $1;    
            next;
        }
        print "$tmppath/$_";
    }
}

sub main()
{
        my @lines = ();

    while (<>) 
    {
        push (@lines, $_);
    }
    format_lines(\@lines);
}

main();

uso:

ls -LR | perl format_ls-LR.pl
Eric Keller
fuente
Este es un terrible programa de Perl. Probablemente sea 2-3 veces más largo y complicado de lo que debe ser.
Brad Gilbert
1

Puede crear una función de shell, por ejemplo, en su .zshrco .bashrc:

filepath() {
    echo $PWD/$1
}

filepath2() {
    for i in $@; do
        echo $PWD/$i
    done
}

El primero solo funcionaría en archivos individuales, obviamente.

rxw
fuente
1

Busque el archivo llamado "nombre de archivo" en su sistema de archivos comenzando la búsqueda desde el directorio raíz "/". El "nombre de archivo"

find / -name "filename" 
user2101432
fuente
1

Si desea preservar los detalles, incluya ls como tamaño de archivo, etc. en su salida, entonces esto debería funcionar.

sed "s|<OLDPATH>|<NEWPATH>|g" input_file > output_file
rajeshk
fuente
1

En el shell de peces , puede hacer esto para enumerar todos los archivos PDF de forma recursiva, incluidos los del directorio actual:

$ ls **pdf

Simplemente elimine 'pdf' si desea archivos de cualquier tipo.

rien333
fuente
0

Puede implementar esta funcionalidad como esta
Primero, usando el comando ls apuntado al directorio de destino. Más tarde, usando el comando find, filtra el resultado de él. Desde su caso, parece que siempre el nombre del archivo comienza con una palabra file***.txt

ls /some/path/here | find . -name 'file*.txt'   (* represents some wild card search)
Sireesh Yarlagadda
fuente
0

En mycase, con comando de árbol

Camino relativo

tree -ifF ./dir | grep -v '^./dir$' | grep -v '.*/$' | grep '\./.*' | while read file; do
  echo $file
done

Camino absoluto

tree -ifF ./dir | grep -v '^./dir$' | grep -v '.*/$' | grep '\./.*' | while read file; do
  echo $file | sed -e "s|^.|$PWD|g"
done
Matsumoto Kazuya
fuente