Írni akarok egy szkriptet, amely csak a bemeneti fájlnév kiterjesztését adja vissza. Például a textfile.txt
vissza kell adnia txt
.
Új vagyok a Linuxban és a bash-ban, és I megpróbálja megtanulni az alapvető szkriptek írását. Köszönöm!
Megjegyzések
Válasz
A shell, például bash, sok karakterlánc-manipuláció funkciók. Az egyik lehetővé teszi, hogy mindent eltávolítson egy adott mintáig:
${VAR##GLOB}
A fenti szintaxis mindent eltávolít az $VAR
a glob GLOB
első mérkőzéséig. Tehát a fájl kiterjesztésének a neve nélküli nyomtatásához tegye a következőket:
$ file="file.txt" $ echo ${file##*.} txt
Ne feledje, hogy ez egynél több “kiterjesztéssel” is foglalkozhat:
$ file="file.new.txt" $ echo ${file##*.} txt
Ha ezt nem szeretné, használjon helyette egy #
-t, amely a legrövidebb egyezést távolítja el a leghosszabbak közül:
$ echo ${file#*.} new.txt
Ha ezt egy könyvtár összes fájlján futtatja, a következőket teheti:
$ 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
A teljesség kedvéért a fájl nevét a kiterjesztés nélkül is megszerezheti a ${file%.*}
használatával:
$ 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
Megjegyzések
- ez nem működik ‘ olyan dolgoknál, mint a foo / .git / bar / baz gondolom meg tudná csinálni az echo test.txt | -t awk -F ‘ / ‘ ‘ {print $ NF} ‘ | awk -F ‘. ‘ ‘ {print $ NF} ‘
- @PaulM mire gondolsz? Ez a ‘ sa kiterjesztés nélküli fájl, mit várhatna ettől?
- 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
. Nem látok ‘ problémát.
Válasz
$ x="textfile.txt" $ echo ${x##*.} txt
A ${parameter##word}
pattern eltávolítja a legnagyobb előtagot, amely megfelel a word
-nek (minden, kivéve a fájlvéget).
Válasz
Egy nagyon egyszerű bash szkript, amely megteheti, amit akar, a következő lenne:
#!/usr/bin/env bash echo "$1" | awk -F "." "{print $NF}"
A szkript script.sh test.txt
, és amit csinál,
-
a
$1
fájlt kinyomtatja a stdout-ba. A$1
az első paraméter, amelyet a szkriptnek adunk, ebben az esetbentest.txt
. -
a
echo
stdout kimenetét a stdin-hez csatolják aawk
fájlhoz, amely szétválasztja a húrt ( >) a.
oldalon, majd kinyomtatja a felosztás utolsó elemét (txt
ebben az esetben).
Csak egy apró megjegyzés, ezt egy vonalhajózással lehet megtenni, mert elég egyszerű feladat:
echo test.txt | awk -F "." "{print $NF}"
Megjegyzések
- Idézetet kell hozzáadnia a
$1
köré, különben kockáztathatja a szóközöket tartalmazó fájlnevek megszakítását. - ez nem működik ‘ olyan dolgoknál, mint a foo / .git / bar / baz. Azt hiszem, meg tudná csinálni az echo test.txt-t
/ ‘ ‘ {print $ NF} ‘ | awk -F ‘.’ ‘ {print $ NF} ‘
Válasz
#!/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"
Futtatás:
./script.sh index.html
Kimenet:
index html
További információ: Shell paraméter kibővítése | gnu.org
Válasz
Ehhez számos figyelmeztetést kell figyelembe venni:
- A
foo.d/bar
fájlnak nincs kiterjesztése, ez nem egyfoo
fájl, amelynek.d/bar
kiterjesztés. - azt is fontolóra veheti, hogy
.bashrc
nincs kiterjesztése - A
.
és a..
speciális címtárfájlokat valószínűleg speciálisan kell kezelni, és úgy kell tekinteni, hogy nincsenek kiterjesztéseik. - minek a kiterjesztése
file.tar.gz
?gz
vagytar.gz
? Mi a helyzet aholiday.picture.jpg
vagy abash-4.4
? - Mit kell adnia a
foo.d/
? Üres vagyd
?
Itt tenném:
#! /bin/sh - for file do case ${file##*/} in (?*.*) ext=${file##*.};; (*) ext=;; esac printf "%s\n" "$ext" done
Megjegyzések
- Kiváló válaszkezelés a szokásos figyelmeztetésekkel és a hasznos kóddal is, főleg funkcióként. / h2>
Még néhány lehetőséget felvetek, ha
sed
vagy Perl telepítve van:#!/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
itt:sed
éss/^.*?\.//&&print
itt:perl
: próbálja meg a legrövidebb karakterláncot helyettesíteni, nem.
, amelyet egy.
karakter követ a karakterlánc elején; ha a helyettesítés megtörténhet, nyomtassa ki a helyettesítés eredményét;
% bash script.sh file.bin Extension: bin Extension: bin
Válasz
Legyen óvatos. Unix / Linux (és MacOS) esetén a “fájlnévkiterjesztés” csak informatív (ha ennyi). Tökéletesen rendelkezhet egy
photo.gif
nevű Perl-szkriptet, vagy egypoem.txt
nevű GIF-fájlt. Vagy akár egysome.txt.png
nevű fájlt.Megjegyzések
- Ez ‘ ugyanolyan informatív az MS Windows rendszerben, de ‘ csak annyi, hogy az alapértelmezett shell program erőteljesebb feltételezéseket tesz a kiterjesztés – tartalom párosítással kapcsolatban, és kell-e lennie egy a név és a tartalom közötti eltérés, az egész általában csak hibákat, szegényeket kezd kiabálni.
-
linux-4.2.3.tar.xz
fájl kiterjesztése, amelyet a kernel.org ? Mi a/bin/bash
fájl kiterjesztése, amely minden bizonnyal elérhető a rendszerén? Látja, hogy a ” fájlkiterjesztés ” fogalma meglehetősen idegen a Linuxban. A pont utáni rész nagyon csekély jelentőséggel bír a rendszer számára – ez inkább a felhasználó figyelmeztetése arra, hogy mit várhat el attól a fájltól. És ez a jel hazudhat vagy téves lehet.