Repete tudo em um diretório?

4

Tudo bem, antes que isso seja fechado imediatamente como duplicata, deixe-me explicar. Eu tentei muitos métodos como:

for d in /Applications ; do
   echo "$d"
done

mas isso retorna

/Applications

em vez do conteúdo de / Applications.

Eu também tentei:

#!/bin/bash
FILES=/Applications

for file in $FILES
do
   echo $file
done

Qual é basicamente a mesma coisa. Notei, porém, que quando eu faço:

#!/bin/bash

for file in *
do
    echo $file
done

Ele ecoa corretamente todas as pastas da minha pasta pessoal. Alguém sabe o que está acontecendo?

    
por Jack 06.09.2016 / 23:25

4 respostas

7
  1. Como anotado por Jeff Schaller , * normalmente funciona como ls - Ele não mostrará coisas cujos nomes começam com . (um período). Se você está usando bash, e você deseja obter coisas cujos nomes começam com . , s et (ativar) o sh ell opt íon dotglob com o comando

    shopt -s dotglob
    

    Isso fará com que * funcione como ls -A . Ele ainda não mostrará . e .. , mas mostrará todo o resto começando com . .

  2. Sua pergunta menciona "tudo em um diretório". Esta é uma frase um tanto ambígua. Se você quer dizer tudo no diretório (nível superior) /Applications , então as outras respostas estão bem. Mas se você quiser tudo na árvore /Applications (isto é, tudo no diretório /Applications e seus subdiretórios ), e você está usando o bash, defina a opção do shell globstar com o comando

    shopt -s globstar
    

    Isso fará com que ** como um componente de nome de arquivo signifique tudo aqui e abaixo. Então

    for file in /Applications/**
    do
        echo "$file"
    done
    

    listará todos os objetos (arquivos, diretórios, etc.) na árvore /Applications .

    Observe que isso não pode ser combinado com outros caracteres no mesmo nível de componente; ou seja, você não pode fazer coisas como foo**bar . No entanto, você acrescenta outros componentes após o ** . Por exemplo,

    for file in /Applications/**/README
    

    percorrerá todos os arquivos denominados README na árvore /Applications , e

    for file in /Applications/**/*.txt
    

    encontrará todos os arquivos cujos nomes terminam com .txt .

  3. Você pode definir várias opções de uma só vez; por exemplo, com

    shopt -s dotglob globstar
    

    Veja a documentação bash para uma lista completa de opções. Você pode u definir opções com shopt -u .

  4. Você deve sempre citar todas as suas referências de variáveis de shell (por exemplo, "$file" ) a menos que você tenha um bom motivo para não e você tem certeza que sabe o que está fazendo.
por 07.09.2016 / 04:02
8

O * é chamado de operador shell globbing (expansão do nome do caminho) ( ? e [] também), quando você o chamar, será expandido para todos os arquivos no diretório atual (sem nenhum prefixo de diretório) ). Se você usar um prefixo, por exemplo /foo/* , ele será expandido para todos os arquivos no diretório /foo .

Observe que ele é usado para corresponder determinados arquivos também, por exemplo, para corresponder apenas aos arquivos que começam com foo e terminam em bar no diretório atual, use o padrão glob:

foo*bar

Assim, o loop for agora pode assumir o formato:

for f in foo*bar; do echo "$f"; done

Leia a página man do seu shell para ter mais ideia sobre a globalização de conchas.

    
por 06.09.2016 / 23:31
8

Para iterar os arquivos (e subdiretórios) em um diretório, você pode usar

for file in /Applications/*
do
    echo "$file"
done

Observe que, se nenhuma correspondência for encontrada, a variável file conterá a string /Applications/* literalmente (com o asterisco), e isso poderá causar erros se os comandos a seguir esperarem um caminho existente. Se você não quiser fazer nada se nenhum arquivo for correspondido, você pode usar a opção nullglob :

shopt -s nullglob
for file in /Applications/*
do
    echo "$file"
done
    
por 06.09.2016 / 23:30
-4

Este formato permite escolher entre todas as opções de listagem e classificação de 'ls':

ls -at $DIR | while read i; do echo $i; done
    
por 07.09.2016 / 02:42