bash: como você retorna extensões de arquivos?

6

Eu quero escrever um script para retornar apenas a extensão do nome do arquivo de entrada. Por exemplo, textfile.txt deve retornar txt .

Sou novo no Linux e no bash e estou tentando aprender a escrever scripts básicos. Obrigado!

    
por user138438 14.10.2015 / 10:48

7 respostas

4

Com a expansão de parâmetros :

$ x="textfile.txt"
$ echo ${x##*.}
txt

O padrão ${parameter##word} remove o maior prefixo que corresponde a word (tudo, exceto o final do arquivo).

    
por 14.10.2015 / 10:54
3

Um script muito simples que poderia fazer o que você quer seria o seguinte:

#!/usr/bin/env bash

echo "$1" | awk -F '.' '{print $NF}'

O script é invocado como script.sh test.txt e o que ele faz é

  • imprime $1 para stdout. $1 é o primeiro parâmetro dado ao script, neste caso test.txt .

  • a saída stdout de echo é canalizada para stdin para awk , que divide a string ( test.txt ) em . e, em seguida, imprime o último elemento da divisão ( txt neste caso).

Apenas uma pequena observação, isso pode ser feito com uma única linha, porque é uma tarefa bastante simples:

echo test.txt | awk -F '.' '{print $NF}'
    
por 14.10.2015 / 10:54
3
#!/bin/bash

my_file='basename "$1"' # get full file name as a script  parameter and strip the path
my_extension="${my_file##*.}"
my_file="${my_file%.*}" # will return base file name before the extension

echo "$my_file"
echo "$my_extension"

Executar:

./script.sh index.html

Saída:

index
html

Mais informações: Expansão do Parâmetro da Shell | gnu.org

    
por 14.10.2015 / 10:58
1

Para fazer isso, há várias ressalvas a serem levadas em conta:

  • O arquivo foo.d/bar não tem extensão, não é um arquivo foo com extensão .d/bar .
  • você também pode querer considerar que .bashrc não tem extensão
  • Os arquivos de diretório especiais . e .. provavelmente devem ser tratados especialmente e considerados como não tendo nenhuma extensão.
  • qual é a extensão para file.tar.gz ? gz ou tar.gz ? Que tal holiday.picture.jpg ou bash-4.4 ?
  • O que você deve retornar para foo.d/ ? Vazio ou d ?

Aqui, eu faria:

#! /bin/sh -
for file do
  case ${file##*/} in
    (?*.*) ext=${file##*.};;
    (*) ext=;;
  esac
  printf '%s\n' "$ext"
done
    
por 15.04.2018 / 09:38
0

Vou colocar mais algumas opções caso você tenha sed ou Perl instalado:

#!/bin/bash
ext=$(<<<"$1" sed -n 's/^[^.]*\.//p')
printf "Extension: $ext\n"
ext=$(<<<"$1" perl -ne 's/^.*?\.//&&print')
printf "Extension: $ext\n"
exit 0
  • s/^[^.]*\.//p in sed e s/^.*?\.//&&print in perl : tente substituir a sequência mais curta de caracteres não . seguida por um caractere . no início da sequência; se a substituição puder ser feita, imprima o resultado da substituição;
% bash script.sh file.bin
Extension: bin
Extension: bin
    
por 14.10.2015 / 19:30
0

Tenha cuidado. No Unix / Linux (e MacOS) a "extensão de nome de arquivo" é apenas informativa (se tanto). Você pode perfeitamente ter um script Perl chamado photo.gif ou um arquivo GIF chamado poem.txt . Ou até mesmo um arquivo chamado some.txt.png .

    
por 14.10.2015 / 21:47