Pesquisando arquivo em um diretório através do script bash

4

Eu escrevi o seguinte código para pesquisar todos os nomes de arquivos no diretório de trabalho atual que contém a letra 'f'.

for i in *
do
  echo $i
  if [ $i = "*f*" ]
  then
    echo "no"
  else
    echo "yes"
  fi
done

Isto imprime "sim" para todos os arquivos presentes nesse diretório, independentemente de conter 'f' ou não. Por favor, corrija o código.

    
por TheHardRock 19.05.2015 / 08:37

5 respostas

5

[ $i = "*f*" ] divide o nome do arquivo armazenado na variável i em palavras separadas em espaços, interpreta cada palavra como um padrão curinga e a expande se corresponder e, em seguida, analisa a lista de palavras resultante como uma condição para% código%. Para evitar essa ladainha e, em vez disso, usar o nome do arquivo, colocam aspas duplas em torno da expansão da variável .

[ … ] testa se o nome do arquivo na variável [ "$i" = "*f*" ] é o nome de três caracteres i . Se você não tiver um arquivo com esse nome, todos os arquivos dispararão o ramo else, então *f* é impresso.

Em ksh, bash ou zsh, você pode testar se uma string corresponde a um padrão curinga usando a construção de colchete duplo. Deixe os curingas no padrão sem aspas.

if [[ "$i" = *f* ]]; then …

Em sh simples, não há sintaxe de colchetes duplos. Para testar se uma string corresponde a um padrão, você pode usar uma construção yes .

case "$i" in
  *f*) echo "no";;
  *) echo "yes";;
esac
    
por 20.05.2015 / 00:57
1

Como você deseja mostrar apenas arquivos que contenham f letter, você precisará do continue builtin. Por exemplo

for f in *; do if [[ $f != *f* ]]; then continue; else printf '%s\n'  "$f yes"; fi; done

Caso você queira mostrar todos os arquivos com os yes ou no correspondentes, você faria algo como:

for f in *; do if [[ $f = *f* ]]; then printf '%s\n' "$f yes"; else printf '%s\n'  "$f no"; fi; done

O acima funciona para diretórios também. Então, se você quiser excluir diretórios, use ! -d $f , por exemplo:

for f in *; do if [[ $f = *f* && ! -d $f ]]; then printf '%s\n' "$f yes"; else printf '%s\n'  "$f no"; fi; done
    
por 19.05.2015 / 09:54
1

O comando test ( [ é sinônimo de "teste" incorporado) não permite padrões.

    STRING1 = STRING2
                 True if the strings are equal.

para comparar as strings letra por letra e claro que não existe arquivo com o nome *f* em seu diretório (assim, seu script de correspondência reversa ecoa yes quando os nomes não correspondem)

Em vez de test -buitin ou mesmo /bin/test você está livre para usar bash keyword [[

When the '==' and '!=' operators are used, the string to the right of
the operator is used as a pattern and pattern matching is performed.
When the '=~' operator is used, the string to the right of the operator
is matched as a regular expression.

Ambos os próximos são utilizáveis:

[[ "$i" == *f* ]]
[[ "$i" =~ f ]]

Mas se você quiser apenas imprimir arquivos do diretório atual com f em seus nomes, o echo é suficiente:

echo *f*
    
por 19.05.2015 / 11:48
1

Este é um exercício de iterações? Se não o uso de encontrar pode ser mais fácil

search=$(find /path/to/dir -type f -name *f*)
echo $search
    
por 19.05.2015 / 13:42
0

Parece que você tem apenas 1 sinal de igual (=) indicando atribuição em vez de um duplo igual (==) indicando uma condição de teste ie. if ($ 1 == " f ")
não if ($ 1=" f ")

    
por 08.06.2018 / 23:57