Repetir arquivos excluindo diretórios

11

Eu preciso do meu script para fazer algo em cada arquivo no diretório atual, excluindo quaisquer subdiretórios.

Por exemplo, no caminho atual, existem 5 arquivos, mas 1 deles é uma pasta (um subdiretório). Meu script deve ativar um comando fornecido como argumento ao executar o script. Ou seja, "bash script wc -w" deve fornecer a contagem de palavras de cada arquivo no diretório atual, mas não de nenhuma das pastas, para que a saída nunca tenha nenhuma das linhas "/ sub / dir: É um diretório".

Meu script atual:

#!/bin/bash
dir=`pwd`
for file in $dir/*
do
    $* $file
done

Eu só preciso excluir diretórios do loop, mas não sei como.

Tõnis Piip
fonte

Respostas:

11
#!/bin/bash -

for file in "$dir"/*
do
  if [ ! -d "$file" ]; then
      "$@" "$file"
  fi
done

Observe que ele também exclui arquivos do tipo link simbólico e onde o link simbólico é resolvido para um arquivo do diretório type (que provavelmente é o que você deseja).

Alternativa (dos comentários), verifique apenas os arquivos:

for file in "$dir"/*
do
  if [ -f "$file" ]; then
      "$@" "$file"
  fi
done
Laktak
fonte
@roaima boa ideia!
Laktak 13/03/19
2
Melhor usar if [ -f "$file" ]; then .... Um diretório não retornaria apenas arquivos comuns, mas também soquetes e links simbólicos.
JRFerguson
@JRFerguson, com base na pergunta do OP, eu diria que incluir soquetes e tubos seria uma péssima idéia. Quanto aos links simbólicos, esses já estão implicitamente incluídos ! -d.
roaima
Eu usei [-f $ file] no meu script final. Observe a falta de aspas na condição if. Quase todo lugar que olhei tinha aspas em torno do arquivo $, mas tive que excluí-las para que meu script funcionasse.
Tõnis Piip
3

Aqui está uma alternativa para usar um loop for se o que você precisa fazer é simples (e não envolve a definição de variáveis ​​no shell principal etc.).

Você pode usar findcom -exece -maxdepth 1para evitar recursão no subdiretório.

[ -n "$1" ] && find "$dir" -type f -mindepth 1 -maxdepth 1 -exec "$@" "{}" \;

O [ -n "$1" ]que há para evitar a execução de todos os arquivos no diretório quando o script não é passado nenhum argumento.

Gregory Nisbet
fonte
2

No zsh, você pode usar os qualificadores globais para restringir as correspondências curinga por tipo de arquivo. Por exemplo, adicionar (.)após o padrão restringe-o a arquivos regulares.

wc -w *(.)

Para lidar com nomes de arquivos que começam com -ou ., use wc -c -- *(.N)ou wc -c ./*(.N). Se você deseja incluir também links simbólicos para arquivos regulares, faça isso *(-.).

Os outros shells comuns não possuem esse recurso, portanto, é necessário usar algum mecanismo diferente para filtrar por arquivo, como testar tipos de arquivo em um loop ou find.

Gilles 'SO- parar de ser mau'
fonte
0

Bash for loop excluindo subdiretórios ('/') e links (@):

for f in `ls|egrep -v '/|@'`; do echo $f; done
James Armstrong
fonte