find . -maxdepth 1 ! -type d
Detalhes:
-
-maxdepth 1
restringe a pesquisa ao diretório atual -
! -type d
elimina diretórios
No bash, como especifico um padrão que corresponda a tudo, exceto subdiretórios no diretório atual. Dado que o padrão */
corresponde a todos os subdiretórios, eu tentei (com o extglob ativado):
$ echo !(*/)
Mas não funcionou.
O motivo */
corresponde aos diretórios é que o% final /
restringe correspondências aos diretórios. Esse efeito só é acionado quando o /
é após um padrão, você não pode usar /
entre parênteses em !(*/)
. Não há recurso embutido no bash para fazer o que você quer.
Você pode fazer um loop sobre todos os arquivos e construir um array.
non_directories=()
for x in *; do
[ -d "$x" ] || non_directories+=("$x")
done
somecommand "${non_directories[@]}"
Você também pode usar find
, se quiser executar um comando sobre todos os arquivos. Se sua implementação find o suportar (GNU, BSD, BusyBox), use -mindepth
e -maxdepth
para listar apenas as entradas nos diretórios atuais (com ./
prefixado). Use ! -name '.*'
para omitir arquivos de ponto (se você quiser omiti-los).
find . -mindepth 1 -maxdepth 1 ! -type d -exec somecommand {} +
Se você só puder assumir um POSIX find
, use -prune
para evitar a recursão.
find . -name . -o -type d -prune -o -exec somecommand {} +
Se você quiser armazenar a saída de find
em uma variável de matriz, tome cuidado, pois a análise da saída de find
exige suposições adicionais no nome do arquivo. Você está melhor com um loop.
Em zsh, você pode usar qualificadores : *(^/)
ou *(.)
para corresponder apenas a arquivos regulares.
Meio longo, mas:
for f in *; do if [ ! -d "$f" ]; then echo "$f"; fi; done
-d
é um operador de teste de arquivo para verificar se o argumento é um diretório.
O texto acima também pode ser encurtado para
for f in *; do [ ! -d "$f" ] && echo "$f"; done
Minha sugestão:
GLOBIGNORE=$(echo */) # create list of directories with globbing
GLOBIGNORE=${GLOBIGNORE//:/\:} # escape possible ":" with "\" to allow
# the separator ":" in directory names
GLOBIGNORE=${GLOBIGNORE//\/ /:} # replace "/ " with separator ":"
GLOBIGNORE=${GLOBIGNORE%/} # remove trailing "/"
ls -ld *
Resultado: nenhum diretório
Voltar para o padrão com unset GLOBIGNORE
Não tenho certeza de qual das duas opções deseja alcançar - bash globing que exclui com base nos atributos do sistema de arquivos ou uma maneira de exibir apenas arquivos em um diretório?
Se o primeiro, não tenho certeza de que isso é possível. Globing apenas se expande, e nomes de arquivos são uma base em qualquer diretório - bash não distingue entre um nome de arquivo ou um nome de diretório por conta própria.
Se o segundo - você já tem 2 respostas, outra usando ls:
ls -dF * | grep -v "/$"