imprimindo todos os diretórios e subdiretórios

0

Estou tentando imprimir todos os subdiretórios, usando a função abaixo, mas, por algum motivo, quando o nome do arquivo inclui espaços (""), o echo divide o nome em duas partes. Aqui está um exemplo:

Meu diretório inclui um arquivo chamado r1 August.request .

A saída é:

r1

August.request

e estou procurando

r1     August.request

Aqui está o meu script:

#!/bin/bash

function ScanFile {
    for file in 'ls' ; do  
    if [[ -d "$file" ]] ; then
            cd "$file"
            ScanFile
            cd ..
            else
            echo "$file"
    fi
    done
} 
ScanFile
    
por Yosef Break 09.08.2018 / 15:04

3 respostas

2

Existe a chamada variável IFS em shells compatíveis com SH. IFS significa Separador de campo interno . Esta variável controla como o shell detecta os limites dos parâmetros, como nos argumentos posicionais.

Por padrão, é:

set IFS=$' \t\n'

Que se traduz em: dividir a entrada em tokens separados por espaço, tabulação e nova linha.

Seus arquivos consistem em espaços em branco. Tente fazer assim:

OLD_IF="$IFS"
IFS=$'\t\n'
for file in 'ls -1' ; do
     # Content of your loop
done
IFS="$OLD_IFS"

Aqui, a captura é armazenar o valor anterior do IFS e restaurá-lo.

Editar: adicionado ls -1 , pois isso lista um arquivo por linha, portanto, faz as coisas que você mencionou.

    
por 09.08.2018 / 15:49
1

No bash:

shopt -s globstar
ls -1d **/
    
por 09.08.2018 / 15:11
0

Sua função analisa a saída sem aspas de ls . Isso significa que o shell executará a divisão de palavras (por padrão, em qualquer espaço em branco) e a geração de nome de arquivo (globbing) na saída de ls .

Em vez disso:

dirwalk () {
    indent=${1:-0}

    for name in *; do
        [ ! -e "$name" ] && continue
        if [ -d "$name" ]; then
            printf '%*sDir: "%s"\n' "$indent" "" "$name"
            ( cd "$name" && dirwalk "$(( indent + 4 ))" )
        else
            printf '%*sFile: "%s"\n' "$indent" "" "$name"
        fi
    done
}

ou, sem o recuo fantasia,

dirwalk () {
    for name in *; do
        [ ! -e "$name" ] && continue
        if [ -d "$name" ]; then
            printf 'Dir: "%s"\n' "$name"
            ( cd "$name" && dirwalk )
        else
            printf 'File: "%s"\n' "$name"
        fi
    done
}

Usando * em vez da saída de ls , geramos uma lista de nomes de arquivos adequadamente delimitada para fazer a iteração no diretório atual, mesmo que contenham espaços.

O teste -e é certificar-se de que a coisa que nós iteramos realmente existe. Se inserirmos um diretório vazio, o * não se expandiria e permaneceria como * . Em bash , você pode definir a opção nullglob shell (com shopt -s nullglob ) para fazer com que padrões incomparáveis sejam expandidos para nada.

Usando cd em um subshell (entre parênteses), não precisamos lembrar de cd .. para voltar ao diretório anterior. O ambiente fora de ( ... ) não seria afetado pelo cd dentro dele.

Usando printf em vez de echo , temos maior controle sobre a formatação da saída. Veja também " Por que printf é melhor que echo? ".

    
por 09.08.2018 / 19:35