Chci napsat skript, který vrátí pouze příponu názvu vstupního souboru. Například textfile.txt
by měl vrátit txt
.
Jsem nový v Linuxu a bash a já snaží se naučit psát základní skripty. Děkujeme!
Komentáře
Odpověď
Shell, například bash, má mnoho manipulace s řetězci . Jeden z nich vám umožní odstranit vše až do daného vzoru:
${VAR##GLOB}
Výše uvedená syntaxe odstraní vše z proměnné $VAR
do první shody glob GLOB
. Chcete-li tedy vytisknout příponu souboru bez jeho názvu, můžete to udělat:
$ file="file.txt" $ echo ${file##*.} txt
Upozorňujeme, že toto může také pracovat s více než jednou „příponou“:
$ file="file.new.txt" $ echo ${file##*.} txt
Pokud to nechcete, použijte místo toho jednu #
, která místo toho odstraní nejkratší shodu z nejdelších:
$ echo ${file#*.} new.txt
Chcete-li to spustit na všech souborech v adresáři, můžete udělat:
$ 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 pro úplnost můžete také získat název souboru bez jeho přípony pomocí ${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
Komentáře
- toto ' nefunguje pro věci jako foo / .git / bar / baz Myslím, že byste mohli udělat echo test.txt | awk -F ' / ' ' {print $ NF} ' | awk -F '. ' ' {print $ NF} '
- @PaulM, co tím myslíš? Tento ' sa soubor bez přípony, co byste od toho očekávali?
- 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
. ' nevidím problém.
Odpovědět
$ x="textfile.txt" $ echo ${x##*.} txt
${parameter##word}
odstraní největší předponu, která odpovídá word
(vše kromě konce souboru).
Odpovědět
Velmi jednoduchý bash skript, který umí dělat to, co chcete, bude následující:
#!/usr/bin/env bash echo "$1" | awk -F "." "{print $NF}"
Skript je vyvolán jako script.sh test.txt
a to, co dělá, je
-
vytiskne
$1
na standardní výstup.$1
je první parametr daný skriptu, v tomto případětest.txt
. -
standardní výstup
echo
je směrován na stdin proawk
, který rozděluje řetězec (test.txt
) na.
a poté vytiskne poslední prvek rozdělení (v tomto případětxt
).
Jen malá poznámka, lze to provést jednorázovou linkou, protože je to docela jednoduchý úkol:
echo test.txt | awk -F "." "{print $NF}"
Komentáře
- Musíte přidat uvozovky kolem
$1
, jinak riskujete rozbití názvů souborů, které obsahují mezery atd. - this does not ' t work for things like foo / .git / bar / baz I guess you could do echo test.txt | awk -F ' / ' ' {print $ NF} ' | awk -F '.' ' {print $ NF} '
Odpověď
#!/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"
Spustit:
./script.sh index.html
Výstup:
index html
Další informace: Rozšíření parametrů shellu | gnu.org
Odpověď
K tomu je třeba vzít v úvahu několik upozornění:
- Soubor
foo.d/bar
nemá příponu, nejedná se o souborfoo
s.d/bar
rozšíření. - můžete také zvážit, že
.bashrc
nemá žádné rozšíření -
.
a..
speciální adresářové soubory by pravděpodobně měly být ošetřeny speciálně a neměly by mít žádnou příponu. - k čemu je přípona
file.tar.gz
?gz
nebotar.gz
? A coholiday.picture.jpg
nebobash-4.4
? - Co byste měli za
foo.d/
? Prázdné nebod
?
Tady udělám:
#! /bin/sh - for file do case ${file##*/} in (?*.*) ext=${file##*.};; (*) ext=;; esac printf "%s\n" "$ext" done
Komentáře
- Vynikající zpracování odpovědí i obvyklých upozornění a užitečného kódu, zejména jako funkce.
Odpověď
Hodím další možnosti, pokud máte sed
nebo Perl nainstalován:
#!/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
vsed
as/^.*?\.//&&print
vperl
: zkuste nahradit nejkratší posloupnost znaků ne.
následovaný znakem.
na začátku řetězce; pokud lze provést náhradu, vytiskněte si výsledek náhrady;
% bash script.sh file.bin Extension: bin Extension: bin
Odpověď
Buďte opatrní. V systémech Unix / Linux (a MacOS) je „přípona názvu souboru“ pouze informativní (je-li tolik). Můžete mít perfektně skript Perl s názvem photo.gif
nebo soubor GIF s názvem poem.txt
. Nebo dokonce soubor s názvem some.txt.png
.
Komentáře
- It ' s stejně informativní v MS Windows, ' s pouze tím, že tam výchozí shell program vytváří silnější předpoklady o párování rozšíření – obsahu, a pokud by existoval nesoulad mezi pojmenováním a obsahem, celá věc obvykle začíná křičet chyby, chudák.
linux-4.2.3.tar.xz
souboru, který si můžete stáhnout z kernel.org ? Jaké je rozšíření souboru/bin/bash
, které je ve vašem systému s největší pravděpodobností k dispozici? Vidíte, koncept " přípony souboru " je v Linuxu docela cizí. Část za tečkou má pro systém velmi malý význam – je to spíše vodítko pro uživatele, co by od tohoto souboru mohl očekávat. A tato narážka může lhát nebo být špatná.