Wie fasst man die Namen der Dateien in jedem Unterverzeichnis in einer Textdatei in diesem Unterverzeichnis zusammen?

Wie fasst man die Namen der Dateien in jedem Unterverzeichnis in einer Textdatei in diesem Unterverzeichnis zusammen?

Ich wollte die Namen aller Dateien in jedem Unterverzeichnis in einer Textdatei in diesem Unterverzeichnis speichern, also habe ich dieses Skript geschrieben:

#!/bin/bash
for X in "$PWD" *
do  
    if [ -d "$X" ];
    then
        cd "$X"
        files="$(ls)"
        echo "$files" >> filesNames.txt
    fi
done

Ich kann jedoch keine Unterverzeichnisse aufrufen mit:

cd "$X"

Was ist hier falsch?

Antwort1

Gemäß Ihren Kommentaren müssen Sie nur eine Ebene tiefer gehen. In diesem Fall könnten Sie einen Glob verwenden, um über Verzeichnisnamen zu iterieren und für jedes Verzeichnis Dateipfade in einem Array zu speichern und dann das letzte Element jedes Pfads wie folgt auszugeben fileNames.txt:

#!/bin/sh

for dir in "$PWD"/*/; do
arr=( "$dir"* )
printf %s\\n "${arr[@]##*/}" > "$dir"filesNames.txt
done

Um Symlinks auszuschließen, fügen Sie einfach eine Bedingung hinzu, z. B.if [[ ! -L "${dir%?}" ]]; then arr...

Antwort2

Sie müssen cdjedes Unterverzeichnis verlassen, bevor Sie das nächste versuchen. Einfügen...

cd ..

am Ende der Schleife würde dies für die Unterverzeichnisse beheben, bricht aber ab, wenn Sie es zuerst im obersten Verzeichnis tun. Ein cd ..von dort bringt Sie eine Ebene nach oben, sodass die anderen Verzeichnisse nicht mehr sichtbar sind.

Sie können all dies beheben, indem Sie das oberste Verzeichnis in einer Variablen speichern und cdjedes Mal dorthin gehen:

#!/bin/bash

TOPDIR="$PWD"
for X in "$PWD" * ; 
do
        if [ -d "$X" ] ;
        then
                cd "$X"
                files="$(ls)"
                echo "$files" >> filesNames.txt
                cd "$TOPDIR"
        fi
done

Möglicherweise möchten Sie auch zu wechseln >>, >wenn Sie nicht alle Ergebnisse aus vorherigen Läufen behalten möchten.

Antwort3

#!/bin/bash
for X in $PWD/* ; do
        if [ -d "$X" ] ; then # first depth directories
                cd "$X" ;
                files="$(ls)" ;
                printf "$files\n" >> filesNames.txt ;
        else # regular files:
                printf "$X\n" >> fileNames.txt ;
        fi ;
done ;

Möglicherweise lässt sich das von Ihnen gewünschte Ergebnis verallgemeinern, indem Sie jeweils findzusätzliche Optionen () verwenden , beispielsweise:man find$X

files=$(find ${PWD} -type f) ;
printf "$files\n" >> filesNames.txt ;

Antwort4

Versuchen Sie stattdessen Folgendes:

find . -type d -exec sh -c "cd {} ; ls | grep -v '^filesNames.txt$' > filesNames.txt" \;

Dadurch werden alle Verzeichnisse unterhalb des aktuellen Verzeichnisses gefunden, und es wird für jedes Verzeichnis cdeine Verzeichnisliste in ein Verzeichnis geschrieben filesNames.txt(wobei die betreffende Datei aus der Liste ausgeschlossen wird).

Wenn die filesNames.txtDateien auch in den Listen enthalten sein sollen, entfernen Sie das | grep -v ...aus dem Befehl:

find . -type d -exec sh -c "cd {} ; ls > filesNames.txt" \;

verwandte Informationen