Как собрать имена файлов в каждом подкаталоге в текстовый файл в этом подкаталоге?

Как собрать имена файлов в каждом подкаталоге в текстовый файл в этом подкаталоге?

Мне нужно было сохранить имена всех файлов в каждом подкаталоге в текстовый файл в этом подкаталоге, поэтому я написал этот скрипт:

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

но я не могу войти в подкаталоги с помощью:

cd "$X"

Что здесь не так?

решение1

Согласно вашим комментариям, вам нужно спуститься только на один уровень вглубь. В этом случае вы могли бы использовать glob для итерации по именам каталогов и для каждого каталога сохранить пути к файлам в массиве, а затем вывести последний элемент каждого пути в fileNames.txt:

#!/bin/sh

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

Чтобы исключить символические ссылки, просто добавьте условие, например:if [[ ! -L "${dir%?}" ]]; then arr...

решение2

Вам нужно cdвыйти из каждого подкаталога, прежде чем пробовать следующий. Вставка...

cd ..

в конце цикла исправит это для подкаталогов, но сломается, если вы сначала сделаете это в верхнем каталоге. A cd ..оттуда перенесет вас на другой уровень выше, так что другие каталоги больше не будут видны.

Вы можете решить все эти проблемы, сохранив верхний каталог в переменной и cdкаждый раз обращаясь к ней:

#!/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

Вы также можете изменить значение >>на >, если не хотите сохранять все результаты предыдущих запусков.

решение3

#!/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 ;

Возможно, то, чего вы пытаетесь достичь, можно обобщить find, используя дополнительные параметры ( man find) для каждого из них $X, например:

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

решение4

Попробуйте вместо этого следующее:

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

Эта команда находит все каталоги ниже текущего каталога, переходит cdв каждый из них и записывает список каталогов в файл filesNames.txt(исключая этот файл из списка).

Если вы хотите, filesNames.txtчтобы файлы также были в списках, удалите | grep -v ...из команды:

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

Связанный контент