durante a iteração no diretório, teste para ver se os itens são arquivos ou diretórios

2

Primeiro, sou mais novo que novo, sinto muito por isso, mas as regras do fórum pedem detalhes.

Também desculpe, isso está sendo estranho.

Aqui está o que estou tentando fazer: estou preso na parte (B)

The script you create must use only relative paths for all paths in the code. You must assume that the script is being run from the ~ directory.

(A) Create a shell script that loops through all items in a directory given by the user using the "read" builtin. The script must validate the input and use a loop to only allow the script to proceed after the validation is complete. It must validate that the directory given is a directory.

(B) The script, while iterating over the items in the directory, should test the items to see if they are directories or files.

  • (B.1) If they are directories then the script needs to loop over the directory and count the number of items inside of the directory (not recursively). The script needs to output both the name of the directory and the number of files (and folders) inside of it to the same line of a file named "~/sorter/directory_listing.txt".

  • (B.2) If they are files they need to be examined for size using du with human readable output. Your script will have to write the size followed by a space then the file name to a new line of the file "~/sorter/files_and_sizes.txt".

(C) After the loop finishes the files_and_sizes.txt file needs to be sorted human readable then output to a file ~/sorter/files_sorted.txt The directory_listing.txt file needs to be sorted reverse by the number of items in the directory and output to a file named ~/sorter/dir_reverse.txt

Minha tentativa:

read -p "Please enter a directory " chosen_dir

while [[ ! -d "$chosen_dir" ]]
do
 echo Please enter a valid directory && read chosen_dir
done

for i in $chosen_dir/*;

    do
        counter=$((counter+1))
        if [ -d "$chosen_dir" ]; then
            ls "$chosen_dir" | wc -l > sorter/directory_listing.txt
        else
            if [ -f "$chosen_dir" ]; then
                du -sh "$chosen_dir"/* > sorter/files_and_sizes.txt
        fi
    done

RESULTADO:

blahblah@vm1:~$ ./taratest.sh
Please enter a directory testsort
./taratest.sh: line 26: syntax error near unexpected token 'done'
./taratest.sh: line 26: '    done'

Quando removo o done , obtenho isto….

NOVO RESULTADO:

blahblah@vm1:~$ ./taratest.sh
Please enter a directory testsort
./taratest.sh: line 27: syntax error: unexpected end of file

ENTÃO: eu procurei aqui por enquanto iterando pelo diretório, teste para ver se os itens são arquivos ou diretórios no bash

e alterado para ISTO:

primeira parte do script, então…

for i in "$chosen_dir"/*

do
    [ -f "$chosen_dir" ] && echo "is File"

    [ -d "$chosen_dir" ] && echo "is Directory"


done

EU SEI O PRODUTO NÃO É O QUE ESTÁ NAS INSTRUÇÕES, ESTOU ECONOMIZANDO APENAS PARA FINS DE TESTE

RESULTADOS:

Please enter a directory testsort

is Directory

is Directory

is Directory

is Directory

2 são arquivos & 2 são dirs., Por que está dizendo 4 dirs

blahblah@vm1:~$ ls -lh testsort
total 8.0K
drwxrwxrwx 2 blahblah student 68 Jun  4 17:41 dir1
drwxrwxrwx 2 blahblah student 68 Jun  4 17:41 dir2
-rwxrwxrwx 1 blahblah student  0 Jun  4 17:41 file1.txt
-rwxrwxrwx 1 blahblah student  0 Jun  4 17:41 file2.txt

Qualquer orientação sobre soluções é muito apreciada.

    
por user173703 06.06.2016 / 02:06

2 respostas

1

O problema é que você tem essa construção:

for [stuff]; do
   if [test]; then
       [stuff]
   else
       if [test]; then
          stuff
   fi
done

Você tem dois if s aninhados, o que é bom, mas você só encerra um deles com fi . Você precisa fazer um destes:

# Alternative one:
for [stuff]; do
   if [test]; then
       [stuff]
   else
       if [test]; then
          stuff
       fi
   fi
done

# Alternative two
for [stuff]; do
   if [test]; then
       [stuff]
   elif [test]; then
       stuff
   fi
done
    
por 06.06.2016 / 02:25
1

Outro problema é que você (corretamente) cita a variável quando a testa com -d , mas não consegue citá-la no loop for .

Em vez de:

for i in $chosen_dir/*;

    do

Uso:

for f in "$chosen_dir"/*; do

(A mudança de nome e a mudança de espaço em branco são pontos de estilo; as aspas duplas adicionadas são importantes.)

Eu não sei o que você está tentando usar o contador, porque você nunca realmente usou. Nem você referiu $i ( $f na minha versão) que, com base na construção for acima, conterá o nome de cada arquivo (ou subdiretório) em "$chosen_dir" , por sua vez.

A propósito, obrigado por especificar que esta é a lição de casa. Poderia haver soluções muito mais curtas, mas sua abordagem geral é válida se você corrigir os erros de sintaxe e também citar suas variáveis .

Para a contagem de arquivos em um subdiretório, você pode não obter uma contagem precisa com o comando que está usando. (Na verdade, você nunca obterá uma contagem precisa com o comando: ls "$chosen_dir" | wc -l porque você não está testando o subdiretório, está testando o diretório digitado pelo usuário.) Em vez de apenas ls , você pode considerar usar ls -1 -A "$i" para que a contagem de linhas forneça uma contagem precisa dos arquivos dentro do subdiretório. (Consulte man ls para detalhes sobre os sinalizadores -1 e -A .)

Isso ainda não irá lidar corretamente com nomes de arquivos que contenham novas linhas, mas para trabalhos de casa eu altamente altamente duvido que você consiga pontos para isso. (Muitos scripts realmente usados na produção também falham em nomes de arquivos que contêm novas linhas; esses nomes vêm apenas de usuários maliciosos.)

Eu assumo que você pode trabalhar a parte C por conta própria. ;) (Veja man sort se você precisar, e procure a tag sort neste site também.)

    
por 06.06.2016 / 04:54