Bash: ls * ohne Ordnergruppierung


12

Wenn ich tippe:

ls source/*

source/fonts:
fontello

source/images:
bg1.png                eng.png        fra.png   

Ich erhalte die Liste der Dateien, gruppiert nach Ordnernamen. Wie kann ich einfach die Liste der Dateinamen erhalten?

ls source/*

source/fonts/fontello
source/images/bg1.png
source/images/eng.png
source/images/fra.png   

Vielen Dank


Wenn dies für die Verwendung von Skripten vorgesehen ist, möchten Sie möglicherweise mywiki.wooledge.org/ParsingLs sehen . (Das heißt, es gibt auch Möglichkeiten, findfalsch zu verwenden . Insbesondere wenn Sie laufen for file in $(find ...), haben Sie eine davon getroffen.)
Charles Duffy

Antworten:


13

Scheint ohne Änderung der Ausgabe nicht möglich zu sein, aber hier ist eine einfache Alternative:

find source/ -type f

Oder (spezifisch für GNU find), um nur Dateien in der Tiefe Ihrer Frage abzurufen:

find source/ -type f -mindepth 2 -maxdepth 2

(oder wenn Sie Verzeichnisse wie lsgeben möchten , entfernen Sie -type f)


5

Sie können sich einfach an ls halten, wenn Sie einige Psychedlics ( ls -d) hinzufügen :

# mkdir test
# cd test
# mkdir A B C
# touch {A,B,C}/file*
# ls -d */*    
A/file  B/file  C/file

@Cthulhu ok mein Beispiel ist zu kurz. Wenn Sie Ordner in A, B a / o C haben, hilft -d, nur das anzuzeigen, was Sie ausgewählt haben. Ich mag es eigentlich nicht zu finden und Sie können die Tiefe durch das Argument mit ls -d
ikrabbe

Ich habe eine Änderung der anderen Antwort vorgeschlagen, um die Tiefe zu begrenzen.
o11c

@ o11c sehr gut, aber immer noch findein dickes Tier.
Ikrabbe

3

Sie könnten an „dem armen Mann find“ interessiert sein :

shopt -s globstar

shopt -s s ets die benannte Shell Option (en). Die globstarOption ist in Bash (1) wie folgt definiert :

Wenn festgelegt, stimmt **das in einem Dateinamen- / Pfadnamen-Erweiterungskontext verwendete Muster mit einer Datei [sic] und null oder mehr Verzeichnissen und Unterverzeichnissen überein . Wenn dem Muster ein folgt /, stimmen nur Verzeichnisse und Unterverzeichnisse überein.

Nachdem Sie dies getan haben shopt -s globstar, können Sie einen der folgenden Befehle ausführen:

ls -d1 - source / **                  # Das Zeichen nach dem 'd' ist die Ziffer. 
ls -d - source / ** | cat             # dh es schreibt das in eine Pipe zu einem beliebigen Befehl. 
printf "% s \ n" source / **

erzeugt die Ausgabe:

source/
source/fonts
source/fonts/fontello
source/images
source/images/bg1.png
source/images/eng.png
source/images/fra.png

Dies schließt leider auch die Verzeichnisnamen ein. Es könnte Ihnen ein wenig helfen, das zu wissen

printf "%s\n" source/**/

erzeugt die Ausgabe:

source/
source/fonts
source/images

dh nur die Verzeichnisnamen. Sie könnten die Ausgabe eines des ersten Satzes von Befehlen in eine Datei, leiten Sie die Ausgabe der oben auf eine zweite Datei umleiten, und dann verwenden comm, diffoder etwas ähnliches, die zweite Datei aus dem ersten abzuziehen, nur die Ebene verlassen Dateien (Nichtverzeichnisse). Aber tu das nicht.

Ein anderer Ansatz (der nicht viel besser ist) ist

ls -d --file-type -- source/** | grep -v '/$'

Die --file-typeOption weist Sie lsan, / am Ende jedes Verzeichnisnamens (und andere Zeichen am Ende anderer (spezieller) Dateitypen) Folgendes anzuzeigen :

source //                             # Eine zusätzliche 
Quelle hinzugefügt / font /                        # Eine hinzugefügt
source / fonts / fontello
Quelle / Bilder /                       # Eine hinzugefügt
source / images / bg1.png
source / images / eng.png
source / images / fra.png

und dann grep -v '/$'entfernt das die Zeilen, die mit enden /; dh die Verzeichnisnamen. Leider wird die --file-typeOption von POSIX nicht angegeben . Wenn Ihre Version lsdies nicht unterstützt, verwenden Sie -F. Das ist so, --file-type außer dass es auch ein *am Ende der Namen ausführbarer Dateien anzeigt , was manche Leute als störend empfinden. Sie können sie beseitigen mit sed:

ls -dF -- source/** | sed -e '/\/$/d' -e 's/\*$//'

Wenn Sie mit allen Dateien (und nur mit den Dateien) etwas tun möchten, können Sie dies tun

für f in source / **
machen
    if [-f "$ f"]
    dann
        Fügen Sie hier Befehle ein, die auf einfache Dateien angewendet werden sollen.
    fi
erledigt

Anmerkungen:

  • Wenn lsmit einem Anschluss ausgegeben wird , und es ist nicht in -l( l ong) Modus, schreibt er mehrere Namen pro Zeile (es sei denn , die Namen sehr lang sind). Sie können erzwingen, einen Namen pro Zeile zu schreiben, indem Sie -1(eins) angeben oder die Ausgabe in eine Datei oder eine Pipe umleiten.
  • Sie wahrscheinlich nicht wirklich brauchen die --in den lsBefehlen , da Sie ein Verzeichnis , dessen Inhalt sind die Auflistung Sie erstellt. Sie sollten es verwenden, wenn Sie *in einem unbekannten Verzeichnis auflisten , um sich vor Dateinamen zu schützen, die mit beginnen -.
  • Versuchen Sie nicht, die Ausgabe von zu analysieren ls.
  • Die globstarShell-Option scheint nicht von POSIX definiert zu sein. (In der Tat, ich bin nicht sicher , POSIX erkennt keine Shell - Optionen.) Während es scheint zu sein bashism, Vorsicht - es ist nicht in allen Versionen von bash vorhanden sein könnten.
  • Wenn fontsoder imagesUnterverzeichnisse hat, **werden sie alle rekursiv bis zum Ende aufgelistet. Eine (etwas klobige und unzuverlässige) Möglichkeit, die Tiefe zu begrenzen, ist

    ls -d --file-type -- source/** | grep -v '\(/.*\)\{3\}'
    

    Dadurch werden Zeilen entfernt, die drei oder mehr /Zeichen enthalten.

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.