Fișier dat nume ca acestea:
/the/path/foo.txt
bar.txt
Sper sa primesc:
foo
bar
De ce acest lucru nu't de lucru?
#!/bin/bash
fullfile=$1
fname=$(basename $fullfile)
fbname=${fname%.*}
echo $fbname
Ce's modul corect de a face asta?
Nu't au pentru a apela extern `basename comandă. În schimb, puteți utiliza următoarele comenzi:
$ s=/the/path/foo.txt
$ echo ${s##*/}
foo.txt
$ s=${s##*/}
$ echo ${s%.txt}
foo
$ echo ${s%.*}
foo
Rețineți că această soluție ar trebui să funcționeze în toate recent (post 2004) POSIX conform scoici, (de exemplu, bash
, bord
, ksh
, etc.).
Sursa: Shell Command Language 2.6.2 Parametru De Expansiune
Mai pe bash Șir de Manipulări: http://tldp.org/LDP/LG/issue18/bash.html
≪a href="http://opengroup.org/onlinepubs/007908799/xcu/basename.html">basename comanda are două diferite invocații; într-o singură, puteți specifica doar calea, în cazul în care acesta vă oferă ultima componentă, în timp ce în alte te oferi, de asemenea, un sufix care se va elimina. Deci, puteți simplifica exemplu de cod cu ajutorul a doua invocare a basename. De asemenea, fii atent să corect citat lucruri:
fbname=$(basename "$1" .txt) echo "$fbname"
O combinație de nume de bază și se taie funcționează bine, chiar și în caz de dublu se încheie ca .tar.gz
:
fbname=$(basename "$fullfile" | cut -d. -f1)
Ar fi interesant dacă această soluție are nevoie de mai puțin de aritmetică putere decât Bash Parametru de Expansiune.
Pur bash
, nu basename
, nici o variabilă de jonglerie. Setați un șir de caractere și "echo":
s=/the/path/foo.txt
echo ${s//+(*\/|.*)}
Ieșire:
foo
Notă: bash
extglob opțiune trebuie să fie "pe", (Ubuntu seturi extglob "pe" în mod implicit), dacă-l's nu, nu:
shopt -s extglob
De mers pe jos prin ${s//+(*\/|.*)}
:
${s
- începe cu $s.//
substitut fiecare exemplu de model.+(
meci una sau mai multe a model de listă în paranteză, (adică până la punctul #7 de mai jos).* \ / meciuri ceva înainte un literal "
/`" char. |
care în acest caz acționează ca un logic SAU..*
meciurile nimic după un literal ".
" - care este, în bash
".
" este doar o perioadă de char, și nu un regex dot.)
end model de listă.}
end parametru de expansiune. Cu un șir de substituție, acolo's, de obicei, un alt /
acolo, urmat de un șir de înlocuire. Dar din moment ce nu's nu /
acolo, potrivite modele sunt substituite cu nimic; aceasta șterge meciurile.Relevant man bash
background:
${parametru/model/string} Model de substituție. Modelul este extins pentru a produce un pat‐ tern la fel ca în pathname de expansiune. Parametrul este extins și cel mai lung meci de model impotriva valoarea acestuia este înlocuită cu șir. Dacă modelul începe cu /, toate meciurile de model sunt înlocuit cu coarde. În mod normal, doar primul meci este înlocuit. Dacă modelul începe cu #, ea trebuie să se potrivească la începe‐ ning a extins valoare de parametru. Dacă modelul începe cu %, ea trebuie să se potrivească la sfârșitul extins valoare de parametru. Dacă șirul este null, se potrivește de model sunt șterse și / fol‐ mugetul model poate fi omisă. Dacă parametrul este @ sau , sub‐ stitution operația se aplică pentru fiecare parametru pozițional în rândul său, și de expansiune este rezultanta lista. Dacă parametrul este o serie de variabile cotizanti cu @ sau , substituirea operația se aplică pentru fiecare membru de matrice, la rândul său, și extinderea este rezultanta lista.
Dacă extglob shell opțiune este activată folosind shopt interna, mai multe extins de model de potrivire operatorii sunt recunoscute. În următoarele descriere, un model-lista este o listă de unul sau mai multe modele separate de o |. Compozit modele pot fi formate folosind una sau mai multe dintre fol‐ mugetul sub-modele:
?(pattern-list) Meciuri zero sau unu apariție a dat modele *(pattern-list) Meciuri zero sau mai multe apariții a dat modele +(pattern-list) se Potrivește cu una sau mai multe apariții a dat modele @(pattern-list) Meciuri unul de modele !(pattern-list) Chibrituri nimic, cu excepția uneia, având modele
Aici este un alt (mai complexe) mod de a obține fie nume sau extensie, utilizați mai întâi " rev " comandă pentru a inversa calea de fișier, a tăiat din prima .
și apoi inversa calea de fișier din nou, ca aceasta:
filename=`rev <<< "$1" | cut -d"." -f2- | rev`
fileext=`rev <<< "$1" | cut -d"." -f1 | rev`
Dacă vrei să joci frumos cu Windows căi de fișiere (sub Cygwin), puteți, de asemenea, încercați acest lucru:
fname=${fullfile##*[/|\\]}
Acest lucru va reprezenta pentru backslash separatoare atunci când se utilizează BaSH pe Windows.
Doar o alternativă cu care am venit, pentru a extrage o extensie, folosind posturile din acest thread cu o mică bază de cunoștințe, care a fost mult mai familiar pentru mine.
ext="$(rev <<< "$(cut -f "1" -d "." <<< "$(rev <<< "file.docx")")")"
Notă: vă Rugăm să sfătui pe utilizarea de citate; ea a lucrat pentru mine, dar mi-ar fi lipsit ceva pe utilizarea lor corectă (am folosi, probabil prea multe).