Pergunta

Estou escrevendo um script noturno de construção em Bash.
Tudo está bem e dândi, exceto por um pequeno problema:


#!/bin/bash

for file in "$PATH_TO_SOMEWHERE"; do
      if [ -d $file ]
      then
              # do something directory-ish
      else
              if [ "$file" == "*.txt" ]       #  this is the snag
              then
                     # do something txt-ish
              fi
      fi
done;

Meu problema é determinar a extensão do arquivo e depois agir de acordo. Eu sei que o problema está na declaração IF, testando um arquivo txt.

Como posso determinar se um arquivo tem um sufixo .txt?

Foi útil?

Solução

Eu acho que você quer dizer "são os últimos quatro caracteres de $ .txt? "Se sim, você pode usar o seguinte:

if [ ${file: -4} == ".txt" ]

Observe que o espaço entre file: e -4 é necessário, como o modificador ':-' significa algo diferente.

Outras dicas

Faço

if [ "$file" == "*.txt" ]

assim:

if [[ $file == *.txt ]]

Isto é, suportes duplos e sem cotações.

O lado direito de == é um padrão de concha. Se você precisar de uma expressão regular, use =~ então.

Você simplesmente não pode ter certeza em um sistema UNIX, de que um arquivo .txt realmente é um arquivo de texto. Sua melhor aposta é usar "arquivo". Talvez tente usar:

file -ib "$file"

Em seguida, você pode usar uma lista de tipos MIME para combinar ou analisar a primeira parte da MIME, onde você obtém coisas como "texto", "aplicativo" etc.

Você pode usar o comando "arquivo" se realmente deseja descobrir informações sobre o arquivo, em vez de confiar nas extensões.

Se você se sentir confortável em usar a extensão, pode usar o Grep para ver se ela corresponde.

Você também pode fazer:

   if [ "${FILE##*.}" = "txt" ]; then
       # operation for txt files here
   fi

Semelhante ao 'arquivo', use o 'Mimetype -b' um pouco mais simples, que funcionará, independentemente da extensão do arquivo.

if [ $(mimetype -b "$MyFile") == "text/plain" ]
then
  echo "this is a text file"
fi

EDIT: Pode ser necessário instalar o libfile-mimeinfo-perl no seu sistema se o mimeType não estiver disponível

Eu escrevi um script bash que analisa o tipo de arquivo e depois copia -o para um local, eu o uso para examinar os vídeos que assisti on -line no meu cache do Firefox:

#!/bin/bash
# flvcache script

CACHE=~/.mozilla/firefox/xxxxxxxx.default/Cache
OUTPUTDIR=~/Videos/flvs
MINFILESIZE=2M

for f in `find $CACHE -size +$MINFILESIZE`
do
    a=$(file $f | cut -f2 -d ' ')
    o=$(basename $f)
    if [ "$a" = "Macromedia" ]
        then
            cp "$f" "$OUTPUTDIR/$o"
    fi
done

nautilus  "$OUTPUTDIR"&

Ele usa idéias semelhantes às apresentadas aqui, espero que isso seja útil para alguém.

eu acho que '$PATH_TO_SOMEWHERE'é algo como '<directory>/*'.

Nesse caso, eu mudaria o código para:

find <directory> -maxdepth 1 -type d -exec ... \;
find <directory> -maxdepth 1 -type f -name "*.txt" -exec ... \;

Se você quiser fazer algo mais complicado com o diretório e os nomes dos arquivos de texto, você pode:

find <directory> -maxdepth 1 -type d | while read dir; do echo $dir; ...; done
find <directory> -maxdepth 1 -type f -name "*.txt" | while read txtfile; do echo $txtfile; ...; done

Se você tiver espaços em seus nomes de arquivos, você pode:

find <directory> -maxdepth 1 -type d | xargs ...
find <directory> -maxdepth 1 -type f -name "*.txt" | xargs ...

A resposta correta sobre como tomar a extensão disponível em um nome de arquivo no Linux é:

${strFileName##*\\.} 

Exemplo de impressão de todas as extensões de arquivo em um diretório

for fname in $(find . -maxdepth 1 -type f) # only regular file in the current dir
    do  echo ${fname##*\.} #print extensions 
done

Minha opinião com corte

>cut -d'.' -f2<<<"hi_mom.txt"
txt

Minha opinião com AWK seria algo como o seguinte.

>MY_DATA_FILE="my_file.sql"
>FILE_EXT=$(awk -F'.' '{print $NF}' <<< $MY_DATA_FILE)
>if [ "sql" = "$FILE_EXT" ]
>then
>   echo "file is sql"
>fi

>awk -F'.' '{print $NF}' <<eof
>hi_mom.txt
>my_file.jpg
>eof
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top