
Eu tenho um diretório chamado 'dir' e nele há um subdiretório chamado 'subdir'. Subdir contém muitos arquivos. Eu gostaria de escrever uma lista desses arquivos em um arquivo CSV e salvá-lo no diretório 'dir' com uma linha de comando no Linux. Meu código cria o arquivo csv, mas o salva no subdiretório, mas não no diretório. Onde eu faço errado? Estou no diretório dir;
dir$ ls subdir >names.csv
Responder1
Como uma alternativa mais fácil, você poderia fazer cd para subdiretório e usar
printf "%s\n" * >../list.csv
Isso lhe dará uma lista separada por nova linha e terminada por nova linha, sem vírgulas envolvidas. Você pode vê-lo como um arquivo CSV degenerado com apenas uma coluna.
Se quiser incluir arquivos ocultos (arquivos com nomes que começam com um ponto), você pode usar * .*
em vez do único arquivo *
. Se você quiser excluir o . e .. nomes de diretório, use * .[^.]* ..?*
em vez disso. No total:
printf "%s\n" * >../list.csv # For non-hidden files.
printf "%s\n" * .* >../list.csv # For all files.
printf "%s\n" * .[^.]* ..?* >../list.csv # For all files but `.` and `..`.
Mas lembre-se de que os nomes de arquivos no Linux podem conter novas linhas por si só. Na verdade, o único separador de byte único para nomes de arquivos é o byte nulo.
Atualização devido aeste comentário:
Suponhamos que você tenha qualquer número de subdiretórios cujo conteúdo não oculto deseja catalogar em arquivos separados no diretório pai comum. (Coletar todos os nomes em um arquivo é muito mais curto, vejaesta solução elegante. E, para dizer a verdade, não li seu comentário com atenção suficiente.) Isso pode ser conseguido naquele diretório pai (dir no seu caso) por
find . -mindepth 1 -maxdepth 1 -type d -exec bash -c 'cd {}; printf "%s\n" * >../$(basename {}).csv' \;
Isso requer os programas find
, bash
, e basename
.
Ao usá-lo, você deve tomar cuidado extra, pois o diretório não contém arquivos cujos nomes entrem em conflito com as listas csv geradas automaticamente.
Veja como funciona: find
considera cada arquivo que está exatamente um nível de diretório abaixo do diretório atual ( .
)—é isso que -mindepth 1 -maxdepth 1
faz—: Se for um diretório ( -type d
) ele executa ( -exec
) o comando entre -exec
e o final \;
após substituir os colchetes vazios ( {}
) pelo nome desse diretório. Se denotarmos esse nome por <SUBDIR>
, isso resulta em
bash -c 'cd <SUBDIR>; printf "%s\n" * >../$(basename <SUBDIR>).csv'
Isso inicia bash
em um subprocesso, fazendo com que ele execute o argumento da -c
opção como um shell script, ou seja,
cd <SUBDIR>;
printf "%s\n" * >../$(basename <SUBDIR>).csv
que é praticamente o mesmo que acima. Aqui, a expressão
$(basename <SUBDIR>)
é expandido para o nome base de <SUBDIR>
. Isso é necessário porque <SUBDIR>
irá iterar através de ./subdir1, ./subdir2, etc no seu caso. Os nomes de base correspondentes são subdir1, subdir2, etc.
Responder2
Você deve conseguir isso usando oparalaço.
Se meu entendimento estiver correto, você deseja obter uma lista de arquivos no subdiretório. Então faça algo assim:
$ cd dir
$ for files in subdir/*;do echo $files|cut -d '/' -f 2 >>filelist.csv;done
Agora, você pode ver que um arquivo chamado "filelist.csv" foi criado em seu diretório dir.