para loop no bash lista as pastas dot e double dot [duplicadas]

3
    

Esta pergunta já tem uma resposta aqui:

    
for f in ~/common/.*; do
    echo $f
done

As entradas listadas são

/home/sk/common/.           #undesired
/home/sk/common/..          #undesired
/home/sk/common/.aliasrc

E estou colocando um truque feio para pular o processamento . e .. para evitar isso,

if [[ $f  == '/home/sk/common/.' || $f  == '/home/sk/common/..' ]]; then
  true 
else
  --do the ops
fi

Existe uma opção de shell que irá esconder o dotted folders ? Estou enfrentando esse problema com ls -a também.

    
por Madhavan Kumar 12.07.2015 / 15:03

7 respostas

5

Aqui está um método usando extglob :

do bash
shopt -s extglob
for f in .!(|.); do
  echo "$f"
done

Com extglob , o padrão !(pattern-list) corresponde a qualquer coisa, exceto pelo padrão fornecido. O padrão no exemplo diz que corresponde a tudo que começa com . e não é seguido por nada ou outro único . .

    
por 12.07.2015 / 16:34
2

Usando find

find ~/common -type f -name ".*" -print0 | \
    while read -d $'
find ~/common -type f -name ".*" -print0 | \
    while IFS= read -rd '' file; \
        do echo $file; \
    done
' file; do \ echo $file; \ done

ou com find e IFS

find ~/common -type f -name ".*" -print0 | \
    while read -d $'
find ~/common -type f -name ".*" -print0 | \
    while IFS= read -rd '' file; \
        do echo $file; \
    done
' file; do \ echo $file; \ done
    
por 12.07.2015 / 16:08
2

A maneira portátil de fazer isso é com uma instrução case - e não faz mal aparar um pouco o globo.

for f in ~/common/.?*; do
    case $f in (*/..)  ;; (*)
    : do something w/ "$f"
    esac
done
    
por 12.07.2015 / 16:49
2

Você quis dizer:

ls -A

você também pode usar

ls -Al

Isto não listará o arquivo. e .. (é a capital A que faz isso). Um irá listar tudo, e A irá listar quase todos, quase todas as causas. e .. não está listado.

EDIT: O acima é destinado a sua segunda pergunta, onde ele afirma que ele tem o mesmo problema com ls -a

    
por 12.07.2015 / 15:16
1

Você precisa modificar seu padrão glob (atualmente * ), provavelmente você está procurando por {[^.],.?}* , então

for f in ~/common/.{[^.],.?}*; do
    echo "$f"
done
    
por 12.07.2015 / 15:26
0

.*[!.]

for f in ~/common/.*[!.]; do
    echo $f
done

Você receberá todos os .[...]foo , mas não . e ..

Adição: para excluir arquivos de links simbólicos:

for f in ~/common/.*[!.]; do
    [[ -L $f ]] || echo $f
done

.note: altere || para && se quiser ecoar apenas os arquivos de links simbólicos.

    
por 12.07.2015 / 16:04
-2
find . -maxdepth 1 -type f | while read f
do
ls -la "$f"
done
    
por 12.07.2015 / 15:06