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
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 casotest.txt
. -
loutput stdout di
echo
viene reindirizzato allo stdin perawk
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 è unfoo
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
otar.gz
? Che ne dici diholiday.picture.jpg
obash-4.4
? - Cosa dovresti restituire per
foo.d/
? Vuoto od
?
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
insed
es/^.*?\.//&&print
inperl
: 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.
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.