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?


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.


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

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.



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.


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».


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

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

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.


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" 

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

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.


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)

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.