Jeg vil skrive et script for kun at returnere udvidelsen af inputfilnavnet. For eksempel skal textfile.txt
returnere txt
.
Jeg er ny til Linux og bash, og jeg “m forsøger at lære at skrive grundlæggende scripts. Tak!
Kommentarer
Svar
Skallen, for eksempel bash, har mange strengmanipulation -funktioner. En af dem lader dig fjerne alt op til et givet mønster:
${VAR##GLOB}
Syntaksen ovenfor fjerner alt fra variablen $VAR
indtil den første kamp på globen GLOB
. Så for at udskrive en fils udvidelse uden dens navn kan du gøre:
$ file="file.txt" $ echo ${file##*.} txt
Bemærk, at dette også kan håndtere mere end en “udvidelse”:
$ file="file.new.txt" $ echo ${file##*.} txt
Hvis du ikke ønsker det, skal du bruge en #
i stedet, som i stedet fjerner den korteste match af den længste:
$ echo ${file#*.} new.txt
For at køre dette på alle filer i en mappe kan du gøre:
$ 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
Og for fuldstændighedens skyld kan du også få filnavnet uden filtypenavn ved hjælp af ${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
- dette fungerer ikke ' t til ting som foo / .git / bar / baz Jeg gætter på, at du kunne lave ekko test.txt | awk -F ' / ' ' {udskriv $ NF} ' | awk -F '. ' ' {udskriv $ NF} '
- @PaulM hvad mener du? Den ' en fil uden filtypenavn, hvad ville du forvente at få af det?
- echo " / foo /var/.git/foo/bar.bz" | awk -F ' / ' ' {udskriv $ NF} ' | awk -F '. ' ' {udskriv $ NF} ' == > > bz
- @PaulM
file="/foo/var/.git/foo/bar.bz"; echo "${file##*.}"
:bz
. Jeg ser ikke ' et problem.
Svar
Med parameterudvidelse :
$ x="textfile.txt" $ echo ${x##*.} txt
${parameter##word}
mønster fjerner det største præfiks, der matcher word
(alt undtagen filen slutter).
Svar
Et meget simpelt bash-script, der kunne gøre, hvad du vil, ville være følgende:
#!/usr/bin/env bash echo "$1" | awk -F "." "{print $NF}"
Scriptet påberåbes som script.sh test.txt
, og hvad det gør er
-
det udskriver
$1
til stdout.$1
er den første parameter, der gives til scriptet, i dette tilfældetest.txt
. -
stdout-output fra
echo
ledes til stdin forawk
som opdeler strengen (test.txt
) på.
og derefter udskriver det sidste element i split (txt
i dette tilfælde).
Bare en lille bemærkning, dette kan gøres med en one-liner, fordi det “er en ret simpel opgave:
echo test.txt | awk -F "." "{print $NF}"
Kommentarer
- Du skal tilføje anførselstegn omkring
$1
, ellers risikerer du at bryde filnavne, der indeholder mellemrum osv. - dette virker ikke ' for ting som foo / .git / bar / baz Jeg antager, at du kunne lave ekko 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
Mere info: Udvidelse af shell-parameter | gnu.org
Svar
For at gøre det er der flere advarsler, der skal tages i betragtning:
-
foo.d/bar
-filen har ingen udvidelse, den er ikke enfoo
-fil med en.d/bar
udvidelse. - Det kan også være en god idé at overveje, at
.bashrc
ikke har nogen udvidelse -
.
og..
specielle katalogfiler bør sandsynligvis behandles specielt og anses for ikke at have nogen udvidelse. - hvad er udvidelsen til
file.tar.gz
?gz
ellertar.gz
? Hvad medholiday.picture.jpg
ellerbash-4.4
? - Hvad skal du returnere til
foo.d/
? Tom ellerd
?
Her gør jeg:
#! /bin/sh - for file do case ${file##*/} in (?*.*) ext=${file##*.};; (*) ext=;; esac printf "%s\n" "$ext" done
Kommentarer
- Fremragende svarhåndtering også de sædvanlige advarsler og nyttig kode, især som en funktion.
Svar
Jeg vil smide nogle flere muligheder, hvis du har sed
eller Perl installeret:
#!/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
ogs/^.*?\.//&&print
iperl
: prøv at erstatte den korteste rækkefølge af tegn, ikke.
efterfulgt af et.
tegn i begyndelsen af strengen; hvis udskiftningen kunne foretages, skal du udskrive resultatet af udskiftningen;
% bash script.sh file.bin Extension: bin Extension: bin
Svar
Vær forsigtig. I Unix / Linux (og MacOS) er “filtypenavnet” bare informativt (hvis så meget). Du kan perfekt have et Perl-script kaldet photo.gif
eller en GIF-fil med navnet poem.txt
. Eller endda en fil med navnet some.txt.png
.
Kommentarer
- Det ' er lige så informativ i MS Windows, det ' er bare, at der inde i standard shell-programmet antager stærkere antagelser om udvidelsen – parring af indhold, og skulle der være en uoverensstemmelse mellem navngivning og indhold, det hele begynder normalt bare at råbe fejl, den stakkels ting.
linux-4.2.3.tar.xz
-fil, som du kan downloade fra kernel.org ? Hvad er den udvidelse af/bin/bash
-fil, der helt sikkert er tilgængelig på dit system? Ser du, begrebet " filtypenavn " er ret fremmed i Linux. Delen efter prikken har meget ringe betydning for systemet – det er snarere et signal for brugeren om, hvad han kunne forvente af den fil. Og det signal kan lyve eller være forkert.