Como reunir o nome dos arquivos de cada subdiretório em um arquivo de texto nesse subdiretório?

Como reunir o nome dos arquivos de cada subdiretório em um arquivo de texto nesse subdiretório?

Eu queria salvar os nomes de todos os arquivos em cada subdiretório em um arquivo de texto nesse subdiretório, então escrevi este script:

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

mas não consigo entrar em subdiretórios usando:

cd "$X"

O que há de errado aqui?

Responder1

De acordo com seus comentários, você só precisa descer um nível de profundidade. Nesse caso, você poderia usar um glob para iterar sobre os nomes dos diretórios e, para cada diretório, salvar os caminhos dos arquivos em uma matriz e, em seguida, imprimir o último elemento de cada caminho para fileNames.txt:

#!/bin/sh

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

Para excluir links simbólicos, basta adicionar uma condição, por exemploif [[ ! -L "${dir%?}" ]]; then arr...

Responder2

Você precisa cdsair de cada subdiretório antes de tentar o próximo. Inserindo...

cd ..

no final do loop corrigiria isso para os subdiretórios, mas seria interrompido quando você fizesse isso primeiro no diretório superior. A cd ..partir daí você subirá outro nível, para que os outros diretórios não fiquem mais visíveis.

Você pode resolver tudo isso salvando o diretório superior em uma variável e cdsempre lá:

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

Você também pode querer mudar >>para >, se não quiser manter todos os resultados de execuções anteriores.

Responder3

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

Pode ser que o que você está tentando alcançar possa ser generalizado usando find- usando opções adicionais ( man find) para cada um $X- como:

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

Responder4

Em vez disso, tente isto:

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

Isso encontra todos os diretórios abaixo do diretório atual e, para cada um, está cdno diretório e grava a listagem de diretórios em a filesNames.txt(excluindo esse arquivo da lista).

Se você quiser que os filesNames.txtarquivos também estejam nas listas, remova o | grep -v ...do comando:

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

informação relacionada