Como cortar a extensão do nome do caminho com ferramentas básicas de unix

3

Eu preciso reunir uma lista de arquivos e colocar isso em um arquivo de texto. No entanto, os arquivos não devem incluir sua extensão.

O comando que tenho agora sem remover as extensões de arquivo:

ls -1 /a/dir/*/dir/* > textfile

Todos os arquivos selecionados terão uma extensão de. [a-z] {3}

(a razão pela qual eu preciso disso é porque eu preciso de uma lista de nomes de base exclusivos, e unique resolverá isso depois dessa etapa)

    
por Peter Smit 30.07.2009 / 13:38

7 respostas

4

Sempre gosto de incluir uma única solução bash:

for file in /a/dir/*/dir/*; do
    echo "${file%.*}" >> ~/file_list
done

e com uma declaração if opcional para limitar o arquivo ao seu ramal solicitado:

shopt -s extglob
for file in /a/dir/*/dir/*; do
    if [[ "$file" =~ \.[a-zA-Z]{3}$ ]]; then
        echo "${file%.*}" >> ~/file_list
    fi
done

Em este serverfault similar pergunta eu explico a expansão do parâmetro "$ {file%. *}".

    
por 30.07.2009 / 14:12
5

Algo assim listaria o arquivo no diretório atual, removendo tudo após o primeiro ponto.

find . -maxdepth 1 -type f | xargs -iZ basename Z | cut -d"." -f1 > /tmp/resultfile

Eventualmente, haveria um problema com arquivos ocultos, resultando em uma linha em branco no arquivo de resultado. Basename está aqui apenas para se livrar do "./" iniciando os nomes dos arquivos no resultado find .

    
por 30.07.2009 / 14:10
3

Que tal:

ls -1 /a/dir/*/dir/* | sed -e 's/\.[a-zA-Z0-9]\{3\}$//'

Deve fazer o que quiser.

    
por 30.07.2009 / 13:44
2

É muito mais simples do que se pensa:

asd@locutus:~$ IZE=file.avi
asd@locutus:~$ echo $IZE
file.avi
asd@locutus:~$ echo ${IZE%%.???}
file
asd@locutus:~$ 

Então, dessa maneira:

ls -1 /a/dir/*/dir/* | while read VAR; do echo ${VAR%.???}; done

Você pode fazer o que quiser entre fazer e fazer, o eco é apenas um exemplo.

man bash (expansão de parâmetro):

   ${parameter%%word}
          The word is expanded to produce a pattern just as in pathname  expansion.
          If the pattern matches a trailing portion of the expanded value of param‐
          eter, then the result of the expansion is the expanded value of parameter
          with the shortest matching pattern (the ‘‘%’’ case) or the longest match‐
          ing pattern (the ‘‘%%’’ case) deleted.  If parameter is @ or *, the  pat‐
          tern  removal  operation is applied to each positional parameter in turn,
          and the expansion is the resultant list.  If parameter is an array  vari‐
          able subscripted with @ or *, the pattern removal operation is applied to
          each member of the array in turn, and  the  expansion  is  the  resultant
          list.

    
por 30.07.2009 / 19:52
1

Uma resposta mais genérica, encontra extensões de qualquer tamanho:

find . -type f | sed 's/^.*\.\([^.]*\)$//'

Eu então uso o seguinte comando para obter uma lista de extensões em um diretório:

find . -type f | sed 's/^.*\.\([^.]*\)$//' | sort | uniq -c | sort -n
    
por 01.03.2011 / 13:33
1

Você também pode usar o corte assim:

for file in /a/dir/*/dir/* ; do
  echo \'echo $file | cut -d"." -f 1' >> textfile;
done

Ele só funcionará se você não tiver nenhum arquivo ou diretório com um "." no nome

    
por 01.12.2014 / 11:50
0

Você deu uma definição explícita para extensões,
Mas as tags linux e bash-scripting sugerem um ambiente unix.
A menos que você esteja fazendo isso com o Cygwin no Windows.
Esses pontos podem não importar nesse caso ...

  • Verifique se você não tem números em sua "extensão" (como md5 )
  • Além disso, e as extensões com menos de três caracteres? ( script.sh )
  • E quanto às extensões com caracteres maiúsculos?
por 30.07.2009 / 13:50

Tags