Listen Sie Dateien rekursiv in der Linux-CLI mit dem Pfad relativ zum aktuellen Verzeichnis auf


224

Dies ähnelt dieser Frage , aber ich möchte den Pfad relativ zum aktuellen Verzeichnis in Unix aufnehmen. Wenn ich folgendes mache:

ls -LR | grep .txt

Es enthält nicht die vollständigen Pfade. Zum Beispiel habe ich die folgende Verzeichnisstruktur:

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

Der obige Code gibt Folgendes zurück:

file.txt
file1.txt
file2.txt

Wie kann ich mithilfe von Unix-Standardbefehlen die Pfade relativ zum aktuellen Verzeichnis einschließen?


4
Dies zeigt nur, dass ls diese Funktion fehlt.
Arjun Singri

1
Es ist eine Schande, dass all diese Lösungen findoder erfordern tree. Ich ssh'ing in ein Android-Gerät, wo ich nur zu haben scheint ls, und keines dieser anderen Tools: /
Ponkadoodle

Antworten:


304

Verwenden Sie find:

find . -name \*.txt -print

Auf Systemen, die GNU find verwenden, wie bei den meisten GNU / Linux-Distributionen, können Sie den -print weglassen.


11
... und für diese Angelegenheit können Sie das '.' weglassen.
Adam Mitz

7
Für absolute Pfade verwenden Siefind $(pwd) -name \*.txt
Zags

2
Wenn Muster einen Teil des Verzeichnisnamens hat, sollte -path "*docs/*.txt"anstelle von verwendet werden -name. -wholenameist das gleiche wie-path
Bindestrich

9
Verwenden Sie -type fdiese Option, um nur Dateien und keine Verzeichnisse, symbolischen Links usw. zurückzugeben
Benutzer

2
-name "*.txt"wird NICHT übereinstimmen file.TXT- verwenden Sie -iname "*.txt"stattdessen immer, wobei die Groß- und Kleinschreibung nicht berücksichtigt wird.
ccpizza

73

Verwenden tree mit -f(vollständiger Pfad) und -i(keine Einrückungslinien):

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

Sie können dann grepdie gewünschten herausfiltern.


Wenn der Befehl nicht gefunden wird, können Sie ihn installieren:

Geben Sie den folgenden Befehl ein, um den Baumbefehl unter RHEL / CentOS und Fedora Linux zu installieren:

# yum install tree -y

Wenn Sie Debian / Ubuntu, Mint Linux verwenden, geben Sie den folgenden Befehl in Ihr Terminal ein:

$ sudo apt-get install tree -y

2
Gibt es eine Einstellung, um nur die Dateien aufzulisten und Ordner auszuschließen?
Thebugfinder

25

Versuchen Sie es find. Sie können es genau in der Manpage nachschlagen, aber es ist irgendwie so:

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

Also für dein Beispiel

find . -name "*.txt"

sollte dir geben, was du willst.



5

Das macht den Trick:

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

Aber es tut dies, indem es mit dem Parsen von "sündigt" ls, was von den GNU- und Ghostscript-Communities als schlechte Form angesehen wird.


2
@CAFEBABE: Es wird als tabu angesehen, die Ergebnisse zu analysieren, lsda dies im Allgemeinen zu Fehlern führt. Der fragliche Satz versuchte das herauszurufen. Es hatte auch einen Witz, den ich entfernt habe.
Adam Katz

4
DIR=your_path
find $DIR | sed 's:""$DIR""::'

'sed' löscht 'your_path' aus allen 'find'-Ergebnissen. Und Sie erhalten relativ zum 'DIR'-Pfad.


das ist genau das, was ich brauche, aber es spuckt immer noch den vollen Weg für mich aus?
v3nt

1
Verwenden Sie nicht die Apostrophe - find / tmp | sed s: "/ tmp" :: | mehr
Kieren Dixon

4

Verwenden Sie den Befehl pwd, um die tatsächlichen vollständigen Pfaddateinamen der gewünschten Dateien mit dem Befehl find abzurufen:

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

1

Hier ist ein Perl-Skript:

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();

Verwendung:

ls -LR | perl format_ls-LR.pl

Dies ist ein schreckliches Perl-Programm. Es ist wahrscheinlich 2-3 mal so lang und kompliziert als es sein muss.
Brad Gilbert

1

Sie können eine Shell-Funktion erstellen, z. B. in Ihrem .zshrcoder .bashrc:

filepath() {
    echo $PWD/$1
}

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

Der erste würde natürlich nur mit einzelnen Dateien funktionieren.


1

Suchen Sie die Datei "Dateiname" in Ihrem Dateisystem und starten Sie die Suche im Stammverzeichnis "/". Der "Dateiname"

find / -name "filename" 

1

Wenn Sie die Details beibehalten möchten, die in Ihrer Ausgabe mit ls wie Dateigröße usw. enthalten sind, sollte dies funktionieren.

sed "s|<OLDPATH>|<NEWPATH>|g" input_file > output_file

1

In der Fischschale können Sie dies tun, um alle PDFs rekursiv aufzulisten, einschließlich derjenigen im aktuellen Verzeichnis:

$ ls **pdf

Entfernen Sie einfach 'pdf', wenn Sie Dateien eines beliebigen Typs möchten.


0

Sie können diese Funktionalität folgendermaßen implementieren.
Verwenden Sie zunächst den Befehl ls, der auf das Zielverzeichnis verweist. Später filtern Sie mit dem Befehl find das Ergebnis daraus. Aus Ihrem Fall klingt es so - immer beginnt der Dateiname mit einem Wort file***.txt

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

0

In meinem Fall mit Baumbefehl

Relativer Pfad

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

Absoluter Pfad

tree -ifF ./dir | grep -v '^./dir$' | grep -v '.*/$' | grep '\./.*' | while read file; do
  echo $file | sed -e "s|^.|$PWD|g"
done
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.