bash: come restituisci le estensioni dei file?

Voglio scrivere uno script per restituire solo lestensione del nome del file di input. Ad esempio, textfile.txt dovrebbe restituire txt.

Sono nuovo di Linux e bash, e io “m cercando di imparare a scrivere script di base. Grazie!

Commenti

  • Vedi anche stackoverflow.com/questions/965053/…
  • Qual è lestensione del file linux-4.2.3.tar.xz che puoi scaricare da kernel.org ? Qual è lestensione del file /bin/bash che è sicuramente disponibile nel tuo sistema? Vedi, il concetto di ” estensione del file ” è piuttosto estraneo in Linux. La parte dopo il punto ha pochissimo significato per il sistema: è piuttosto un indizio per lutente su cosa potrebbe aspettarsi da quel file. E questo indizio potrebbe mentire o essere sbagliato.

Risposta

La shell, bash per esempio, ne ha molti manipolazione delle stringhe . Uno di questi ti consente di rimuovere tutto fino a un determinato modello:

${VAR##GLOB} 

La sintassi precedente rimuove tutto dalla variabile $VAR fino alla prima corrispondenza del glob GLOB. Quindi, per stampare lestensione di un file senza il suo nome, potresti fare:

$ file="file.txt" $ echo ${file##*.} txt 

Nota che questo può anche gestire più di una “estensione”:

$ file="file.new.txt" $ echo ${file##*.} txt 

Se non lo desideri, usa uno #, che rimuoverà invece la corrispondenza più breve del più lungo:

$ echo ${file#*.} new.txt 

Ora, per eseguirlo su tutti i file in una directory, puoi fare:

$ ls file.avi file.pdf file.png file.txt $ for file in *; do echo "$file : ${file##*.}"; done file.avi : avi file.pdf : pdf file.png : png file.txt : txt 

Inoltre, per motivi di completezza, puoi anche ottenere il nome del file senza la sua estensione utilizzando ${file%.*}:

$ for file in *; do echo "$file : ${file##*.} : ${file%.*}"; done file.avi : avi : file file.pdf : pdf : file file.png : png : file file.txt : txt : file 

Commenti

  • questo ‘ t funziona per cose come foo / .git / bar / baz Immagino che potresti fare echo test.txt | awk -F ‘ / ‘ ‘ {print $ NF} ‘ | awk -F ‘. ‘ ‘ {print $ NF} ‘
  • @PaulM cosa intendi? Quel ‘ file sa senza estensione, cosa ti aspetteresti di ottenere da quello?
  • echo ” / foo /var/.git/foo/bar.bz” | awk -F ‘ / ‘ ‘ {print $ NF} ‘ | awk -F ‘. ‘ ‘ {print $ NF} ‘ == > > bz
  • @PaulM file="/foo/var/.git/foo/bar.bz"; echo "${file##*.}": bz. Non ‘ non vedo un problema.

Risposta

Con espansione del parametro :

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

${parameter##word} pattern rimuove il prefisso più grande che corrisponde a word (tutto tranne la fine del file).

Risposta

Uno script bash molto semplice che potrebbe fare quello che vuoi sarebbe il seguente:

#!/usr/bin/env bash echo "$1" | awk -F "." "{print $NF}" 

Lo script viene richiamato come script.sh test.txt, e ciò che fa è

  • stampa $1 su stdout. $1 è il primo parametro fornito allo script, in questo caso test.txt.

  • loutput stdout di echo viene reindirizzato allo stdin per awk che divide la stringa (test.txt) su . e quindi stampa lultimo elemento della divisione (txt in questo caso).

Solo una piccola osservazione, questo può essere fatto con una battuta perché “è un compito piuttosto semplice:

echo test.txt | awk -F "." "{print $NF}" 

Commenti

  • Devi aggiungere virgolette intorno a $1, altrimenti rischi di rompere i nomi di file che contengono spazi ecc.
  • questo ‘ non funziona per cose come foo / .git / bar / baz Immagino che potresti fare echo test.txt | awk -F ‘ / ‘ ‘ {print $ NF} ‘ | awk -F ‘.’ ‘ {print $ NF} ‘

Risposta

#!/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" 

Esegui:

./script.sh index.html 

Risultato:

index html 

Altre informazioni: Espansione dei parametri della shell | gnu.org

Risposta

Per fare ciò, ci sono diversi avvertimenti da tenere in considerazione:

  • Il file foo.d/bar non ha estensione, “non è un foo file con un .d/bar estensione.
  • potresti anche considerare che .bashrc non ha estensione
  • . e .. file di directory speciali dovrebbero probabilmente essere trattati in modo speciale e considerati privi di estensione.
  • qual è lestensione per file.tar.gz? gz o tar.gz? Che ne dici di holiday.picture.jpg o bash-4.4?
  • Cosa dovresti restituire per foo.d/? Vuoto o d?

Qui, io “farei:

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

Commenti

  • Ottima risposta che gestisce anche i soliti avvertimenti e codice utile soprattutto come funzione.

Risposta

Inserirò altre opzioni nel caso tu abbia sed o Perl installato:

 #!/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: prova a sostituire la sequenza di caratteri più breve non . seguito da un carattere . allinizio della stringa; se è possibile effettuare la sostituzione, stampa il risultato della sostituzione;
 % bash script.sh file.bin Extension: bin Extension: bin  

Risposta

Fai attenzione. In Unix / Linux (e MacOS) “lestensione del nome del file” è solo informativa (se così tanto). Puoi perfettamente avere uno script Perl chiamato photo.gif, o un file GIF chiamato poem.txt. O anche un file chiamato some.txt.png.

Commenti

  • It ‘ è altrettanto informativo in MS Windows, ‘ è solo che lì il programma shell predefinito fa supposizioni più forti sullassociazione estensione-contenuto, e dovrebbe esserci un discrepanza tra denominazione e contenuto, il tutto di solito inizia a gridare errori, il poveretto.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *