Liste les fichiers de manière récursive dans Linux CLI avec le chemin relatif au répertoire courant

224

C'est similaire à cette question , mais je veux inclure le chemin d'accès par rapport au répertoire courant sous unix. Si je fais ce qui suit:

ls -LR | grep .txt

Il n'inclut pas les chemins d'accès complets. Par exemple, j'ai la structure de répertoires suivante:

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

Le code ci-dessus renverra:

file.txt
file1.txt
file2.txt

Comment puis-je le faire inclure les chemins relatifs au répertoire courant en utilisant les commandes Unix standard?

Darryl Hein
la source
4
Cela montre simplement que ls n'a pas cette fonctionnalité.
Arjun Singri
1
C'est dommage que toutes ces solutions nécessitent findou tree. Je ssh'ing dans un appareil Android où je semble avoir seulement ls, et aucun de ces autres outils: /
Ponkadoodle

Réponses:

304

Utilisez find:

find . -name \*.txt -print

Sur les systèmes qui utilisent GNU find, comme la plupart des distributions GNU / Linux, vous pouvez omettre l'impression.

Andru Luvisi
la source
11
... et d'ailleurs vous pouvez laisser de côté le '.'
Adam Mitz
7
Pour les chemins absolus, utilisezfind $(pwd) -name \*.txt
Zags
2
Si le motif contient une partie du nom du répertoire, il faut utiliser à la -path "*docs/*.txt"place de -name. -wholenameest le même que-path
dashesy
9
Utilisez -type fpour renvoyer uniquement des fichiers et non des répertoires, des liens symboliques, etc.
utilisateur
2
-name "*.txt"ne pas correspondre file.TXT- toujours utiliser au -iname "*.txt"lieu qui est insensible à la casse.
ccpizza
73

Utilisez tree, avec -f(chemin complet) et -i(pas de lignes de retrait):

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

Vous pouvez ensuite utiliser greppour filtrer ceux que vous souhaitez.


Si la commande n'est pas trouvée, vous pouvez l'installer:

Tapez la commande suivante pour installer la commande d'arborescence sur RHEL / CentOS et Fedora linux:

# yum install tree -y

Si vous utilisez Debian / Ubuntu, tapez la commande Mint Linux suivante dans votre terminal:

$ sudo apt-get install tree -y
Stephen Irons
la source
2
un paramètre pour répertorier uniquement les fichiers et exclure les dossiers?
thebugfinder
25

Essayez find. Vous pouvez le rechercher exactement dans la page de manuel, mais c'est comme ceci:

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

donc pour votre exemple

find . -name "*.txt"

devrait vous donner ce que vous voulez.

Jonathan Adelson
la source
9

Vous pouvez utiliser find à la place:

find . -name '*.txt'
Sherm Pendley
la source
5

Cela fait l'affaire:

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

Mais il le fait en "péchant" avec l'analyse de ls, ce qui est considéré comme une mauvaise forme par les communautés GNU et Ghostscript.

El Guesto
la source
2
@CAFEBABE: il est considéré comme tabou d'analyser les résultats lscar cela conduit généralement à des bugs. La phrase en question essayait de le rappeler. Il y avait aussi une blague que j'ai retirée.
Adam Katz
4
DIR=your_path
find $DIR | sed 's:""$DIR""::'

'sed' effacera 'your_path' de tous les résultats 'find'. Et vous recevez par rapport au chemin «DIR».

h-dima
la source
c'est exactement ce dont j'ai besoin mais ça crache toujours le chemin complet pour moi?
v3nt
1
n'utilisez pas l'apostrophe - find / tmp | sed s: "/ tmp" :: | plus
Kieren Dixon
4

Pour obtenir les noms de fichier de chemin complet réels des fichiers souhaités à l'aide de la commande find, utilisez-le avec la commande pwd:

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

Voici un script 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();

usage:

ls -LR | perl format_ls-LR.pl
Eric Keller
la source
C'est un terrible programme Perl. C'est probablement 2-3 fois plus long et compliqué que nécessaire.
Brad Gilbert
1

Vous pouvez créer une fonction shell, par exemple dans votre .zshrcou .bashrc:

filepath() {
    echo $PWD/$1
}

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

Évidemment, le premier ne fonctionnerait que sur des fichiers uniques.

rxw
la source
1

Trouvez le fichier appelé "nom de fichier" sur votre système de fichiers en commençant la recherche à partir du répertoire racine "/". Le "nom de fichier"

find / -name "filename" 
user2101432
la source
1

Si vous souhaitez conserver les détails fournis avec ls comme la taille du fichier, etc. dans votre sortie, cela devrait fonctionner.

sed "s|<OLDPATH>|<NEWPATH>|g" input_file > output_file
Rajeshk
la source
1

Dans le shell de poissons , vous pouvez faire cela pour lister tous les fichiers PDF de manière récursive, y compris ceux du répertoire courant:

$ ls **pdf

Supprimez simplement 'pdf' si vous voulez des fichiers de tout type.

rien333
la source
0

Vous pouvez implémenter cette fonctionnalité comme ceci
Premièrement, en utilisant la commande ls pointant vers le répertoire cible. Plus tard, en utilisant la commande find, filtrez le résultat. D'après votre cas, cela ressemble à - toujours le nom de fichier commence par un mot file***.txt

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

Dans mycase, avec la commande tree

Chemin relatif

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

Chemin absolu

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