Jag vill skriva ett skript för att bara returnera tillägget till inmatningsfilnamnet. Till exempel ska textfile.txt
returnera txt
.
Jag är ny till Linux och bash och jag ”m försöker lära sig att skriva grundläggande manus. Tack!
Kommentarer
Svar
Skalet, till exempel bash, har många funktioner för strängmanipulation . En av dem låter dig ta bort allt upp till ett visst mönster:
${VAR##GLOB}
Syntaxen ovan tar bort allt från variabeln $VAR
tills globens första match GLOB
. Så för att skriva ut ett filtillägg utan dess namn kan du göra:
$ file="file.txt" $ echo ${file##*.} txt
Observera att detta också kan hantera mer än ett ”tillägg”:
$ file="file.new.txt" $ echo ${file##*.} txt
Om du inte vill ha det, använd en #
istället för att ta bort den kortaste matchen istället av den längsta:
$ echo ${file#*.} new.txt
För att köra detta på alla filer i en katalog kan du göra:
$ 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
Och för fullständighetens skull kan du också få filnamnet utan dess tillägg med ${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
Kommentarer
- det fungerar inte ' för saker som foo / .git / bar / baz Jag antar att du kan göra echo test.txt | awk -F ' / ' ' {print $ NF} ' | awk -F '. ' ' {print $ NF} '
- @PaulM vad menar du? Den ' en fil utan tillägg, vad kan du förvänta dig att få från det?
- 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
. Jag ser inte ' ett problem.
Svar
Med parameterutvidgning :
$ x="textfile.txt" $ echo ${x##*.} txt
${parameter##word}
mönster tar bort det största prefixet som matchar word
(allt utom filen som slutar).
Svar
Ett mycket enkelt bash-skript som kan göra vad du vill skulle vara följande:
#!/usr/bin/env bash echo "$1" | awk -F "." "{print $NF}"
Skriptet anropas som script.sh test.txt
, och vad det gör är
-
det skriver ut
$1
till stdout.$1
är den första parametern som ges till skriptet, i detta falltest.txt
. -
stdout-utgången för
echo
skickas till stdin förawk
som delar upp strängen (test.txt
) på.
och sedan skrivs det sista elementet i delningen ut (txt
i detta fall).
Bara en liten anmärkning, detta kan göras med en enfodrad eftersom det är en ganska enkel uppgift:
echo test.txt | awk -F "." "{print $NF}"
Kommentarer
- Du måste lägga till citat runt
$1
, annars riskerar du att bryta filnamn som innehåller mellanslag etc. - det fungerar inte ' för saker som foo / .git / bar / baz Jag antar att du kan göra echo test.txt | awk -F ' / ' ' {print $ NF} ' | awk -F '.' ' {print $ NF} '
Svar
#!/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"
Kör:
./script.sh index.html
Output:
index html
Mer info: Expansion av skalparameter | gnu.org
Svar
För att göra det finns det flera försiktighetsåtgärder att ta hänsyn till:
-
foo.d/bar
-filen har inget tillägg, den är inte enfoo
-fil med en.d/bar
förlängning. - Du kanske också vill överväga att
.bashrc
inte har något tillägg -
.
och..
specialkatalogfiler bör antagligen behandlas speciellt och anses inte ha något tillägg. - vad är tillägget för
file.tar.gz
?gz
ellertar.gz
? Vad sägs omholiday.picture.jpg
ellerbash-4.4
? - Vad ska du returnera för
foo.d/
? Tom ellerd
?
Här skulle jag göra:
#! /bin/sh - for file do case ${file##*/} in (?*.*) ext=${file##*.};; (*) ext=;; esac printf "%s\n" "$ext" done
Kommentarer
- Utmärkt svarhantering också vanliga försiktighetsåtgärder och användbar kod särskilt som en funktion.
Svar
Jag kastar in några fler alternativ om du har sed
eller Perl installerad:
#!/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
ised
ochs/^.*?\.//&&print
iperl
: försök att ersätta den kortaste sekvensen med tecken inte.
följt av ett.
-tecken i början av strängen; om utbytet kunde göras, skriv ut resultatet av utbytet;
% bash script.sh file.bin Extension: bin Extension: bin
Svar
Var försiktig. I Unix / Linux (och MacOS) är ”filnamnstillägget” bara informativt (om så mycket). Du kan perfekt ha ett Perl-skript som heter photo.gif
eller en GIF-fil med namnet poem.txt
. Eller till och med en fil som heter some.txt.png
.
Kommentarer
- Det ' är lika informativt i MS Windows, det ' är bara att det finns standardskalprogrammet starkare antaganden om tillägget – innehållsparning, och om det skulle finnas en oöverensstämmelse mellan namngivning och innehåll, det hela börjar vanligtvis bara ropa fel, det dåliga.
linux-4.2.3.tar.xz
-fil som du kan ladda ner från kernel.org ? Vad är förlängningen av/bin/bash
-filen som säkert finns på ditt system? Du förstår att begreppet " filtillägg " är ganska främmande i Linux. Delen efter punkten har väldigt liten betydelse för systemet – det är snarare en ledtråd för användaren om vad han kan förvänta sig av den filen. Och den ledtråden kan ljuga eller vara fel.