Ištraukite failo pavadinimą ir plėtinį bash

Noriu gauti failo pavadinimą (be plėtinio) ir plėtinį atskirai.

Geriausias rastas sprendimas yra:

 NAME='echo "$FILE" | cut -d'.' -f1' EXTENSION='echo "$FILE" | cut -d'.' -f2' 

Tai neteisinga, nes ji neveikia, jei failo pavadinime yra keletas . simbolių Jei, tarkim, turiu abjs , jis apsvarstys a ir b.js vietoj ab ir js .

Tai galima lengvai atlikti „Python“ sistemoje

 file, ext = os.path.splitext(path) 

bet aš nenorėčiau paleisti „Python“ vertėjo tik tuo atveju, jei įmanoma.

Ar yra geresnių idėjų?

1716
08 июня '09 в 17:00 2009-06-08 17:00 „ibz“ yra nustatytas birželio 8 d. 09 val. 17:00 2009-06-08 17:00
@ 36 atsakymai
  • 1
  • 2

Pirmiausia gaukite failo pavadinimą be kelio

 filename=$(basename -- "$fullfile") extension="${filename##*.}" filename="${filename%.*}" 

Be to, galite sutelkti dėmesį į paskutinį „/“ kelią vietoj „“. kuris turėtų veikti net ir tuo atveju, jei turite nenuspėjamų failų plėtinių:

 filename="${fullfile##*/}" 

Galite patikrinti dokumentaciją:

2944
08 июня '09 в 17:05 2009-06-08 17:05 atsakymą pateikė „ Petesh “ birželio 08 d. 09:17 val. 2009-06-08 17:05
 ~% FILE="example.tar.gz" ~% echo "${FILE%%.*}" example ~% echo "${FILE%.*}" example.tar ~% echo "${FILE#*.}" tar.gz ~% echo "${FILE##*.}" gz 

Išsamesnės informacijos apie korpuso parametrų išplėtimą žr.

527
08 июня '09 в 17:05 2009-06-08 17:05 Atsakymą davė Juliano 08-08-09 17:05 2009-06-08 17:05

Paprastai jau žinote išplėtimą, todėl galite naudoti:

 basename filename .extension 

pavyzdžiui:

 basename /path/to/dir/filename.txt .txt 

ir gaukite

 filename 
306
19 окт. Atsakyti Tomi Po 19 okt. 2011-10-19 13:56 '11, 13:56, 2011-10-19 13:56

Galite naudoti POSIX kintamųjų magiją:

 bash-3.2$ FILENAME=somefile.tar.gz bash-3.2$ echo ${FILENAME%%.*} somefile bash-3.2$ echo ${FILENAME%.*} somefile.tar 

Yra įspėjimas, kad jei jūsų failo pavadinime yra ./somefile.tar.gz forma, tada echo ${FILENAME%%.*} Ar norite ištrinti ilgiausią atitikimą . ir jūs turėsite tuščią eilutę.

(Galite tai apsispręsti naudodami laikiną kintamąjį:

 FULL_FILENAME=$FILENAME FILENAME=${FULL_FILENAME##*/} echo ${FILENAME%%.*} 

)


Ši svetainė paaiškina daugiau.

 ${variable%pattern} Trim the shortest match from the end ${variable##pattern} Trim the longest match from the beginning ${variable%%pattern} Trim the longest match from the end ${variable#pattern} Trim the shortest match from the beginning 
128
05 февр. atsakymas pateikiamas sotapme 05 feb . 2013-02-05 12:09 '13, 12:09 2013-02-05 12:09

Tai neveikia, jei failas neturi plėtinio ar failo pavadinimo. Štai ką aš naudoju; ji naudoja tik įterptą ir tvarko daugiau (bet ne visų) patologinių failų pavadinimus.

 #!/bin/bash for fullpath in "$@" do filename="${fullpath##*/}" # Strip longest match of */ from start dir="${fullpath:0:${#fullpath} - ${#filename}}" # Substring from 0 thru pos of filename base="${filename%.[^.]*}" # Strip shortest match of . plus at least one non-dot char from end ext="${filename:${#base} + 1}" # Substring from len of base thru end if [[ -z "$base"  -n "$ext" ]]; then # If we have an extension and no base, it really the base base=".$ext" ext="" fi echo -e "$fullpath:\n\tdir = \"$dir\"\n\tbase = \"$base\"\n\text = \"$ext\"" done 

Ir čia yra keletas bandymų pavyzdžių:

 $ basename-and-extension.sh / / home / me / / home / me / failas /home/me/file.tar /home/me/file.tar.gz /home/me/.hidden / home / me / .hidden.tar / home / me / ... /: dir = "/" base = "" ext = "" / home / me /: dir = "/ home / me /" base = "" ext = "" / home / me / failas: dir = "/ home / me /" base = "file" ext = "" /home/me/file.tar: dir = "/ home / me /" base = "file" ext = "tar" /home/me/file.tar.gz: dir = "/ home / me /" base = "file.tar" ext = "gz" /home/me/.hidden: dir = "/ home / me /" base = ".hidden" ext = "" /home/me/.hidden.tar: dir = "/ home / me /" base = ".hidden" ext = "tar" / home / me / ..: dir = "/ home / me /" base = ".." ext = "" .: dir = "" base = "." ext = ""
66
10 сент. Atsakymą pateikia daktaras J 10 Sep. 2009-09-10 08:17 '09 8:17 am. 2009-09-10 08:17

Galite naudoti pagrindinį basename .

Pavyzdys:

 $ basename foo-bar.tar.gz .tar.gz foo-bar 

Turite pateikti pagrindinį pavadinimą su plėtiniu, kurį reikia pašalinti, bet jei visada vykdote -z su -z , žinote, kad plėtinys bus .tar.gz .

Tai turėtų daryti tai, ko norite:

 tar -zxvf $1 cd $(basename $1 .tar.gz) 
42
05 февр. Atsakymą pateikė Bjarke Freund-Hansen 05 vasaris. 2013-02-05 11:50 '13, 11:50, 2013-02-05 11:50
 pax> echo abjs | sed 's/\.[^.]*$//' ab pax> echo abjs | sed 's/^.*\.//' js 

veikia gerai, todėl galite naudoti:

 pax> FILE=abjs pax> NAME=$(echo "$FILE" | sed 's/\.[^.]*$//') pax> EXTENSION=$(echo "$FILE" | sed 's/^.*\.//') pax> echo $NAME ab pax> echo $EXTENSION js 

Komandos, beje, dirba taip.

NAME komanda pakeičia „ "." po bet kokio simbolių skaičiaus "." iki linijos pabaigos, niekas (t.y., ištrina viską nuo galutinio "." iki linijos pabaigos, įskaitant). Tai iš esmės yra ne gobšus pakaitalas naudojant reguliarias išraiškas.

EXTENSION komanda pakeičia bet kokį simbolių skaičių ir po jo "." linijos pradžioje, be nieko (t.y., ištrina viską nuo eilutės pradžios iki galutinio taško imtinai), tai yra godus pakaitalas, kuris yra numatytasis veiksmas.

27
08 июня '09 в 17:14 2009-06-08 17:14 Atsakymas pateikiamas paxdiablo birželio 8 d. 09:17 17:14 2009-06-08 17:14

Mellen rašo komentarą dienoraščio įraše:

Naudodamiesi bash, galite taip pat ${file%.*} Gauti failo pavadinimą be plėtinio ir ${file##*.} . Tai yra

 file="thisfile.txt" echo "filename: ${file%.*}" echo "extension: ${file##*.}" 

Rezultatai:

 filename: thisfile extension: txt 
26
21 июля '10 в 13:24 2010-07-21 13:24 Kebabberto atsakymas liepos 21 d. 10 val. 13:24 2010-07-21 13:24

Galite naudoti cut kad pašalintumėte paskutinius du plėtinius ( ".tar.gz" ):

 $ echo "foo.tar.gz" | cut -d'.' --complement -f2- foo 

Kaip komentare pažymėjo Clayton Hughes, tai neveiks dėl konkretaus pavyzdžio. Todėl, kaip alternatyvą, siūlau naudoti sed su išplėstinėmis reguliariomis išraiškomis, pavyzdžiui:

 $ echo "mpc-1.0.1.tar.gz" | sed -r 's/\.[[:alnum:]]+\.[[:alnum:]]+$//' mpc-1.0.1 

Jis veikia pašalindamas paskutinius du (raidinius ir skaitmeninius) plėtinius be jokių sąlygų.

[Atnaujinta po komentaro Anders Lindal]

23
05 февр. atsakymą pateikė „ Some programmer dude 05 feb“. 2013-02-05 11:53 '13, 11:53, 2013-02-05 11:53

Nereikia nerimauti dėl awk ar sed ar net perl dėl šios paprastos užduoties. Yra grynas Bash, os.path.splitext() sprendimas, kuris naudoja tik parametrų išplėtimus.

Nuorodos įgyvendinimas

Dokumentacija os.path.splitext(path) :

Padalinkite kelią poroje (root, ext) , kad root + ext == path ir ext būtų tuščias arba prasideda nuo laikotarpio ir jame yra ne daugiau kaip vienas laikotarpis. Pagrindiniai pavadinimai yra ignoruojami; splitext('.cshrc') grąžina ('.cshrc', '') .

„Python“ kodas:

 root, ext = os.path.splitext(path) 

Bash įgyvendinimas

Pagrindinių laikotarpių gerbimas

 root="${path%.*}" ext="${path#"$root"}" 

Nepaisoma pagrindinių laikotarpių

 root="${path#.}";root="${path%"$root"}${root%.*}" ext="${path#"$root"}" 

Bandymai

Toliau pateikiami pavyzdiniai pavyzdžiai, kaip ignoruoti pagrindinius laikotarpius, kurie turi atitikti Python nuorodų įgyvendinimą kiekviename įraše.

 |---------------|-----------|-------| |path |root |ext | |---------------|-----------|-------| |' .txt' |' ' |'.txt' | |' .txt.txt' |' .txt' |'.txt' | |' txt' |' txt' |'' | |'*.txt.txt' |'*.txt' |'.txt' | |'.cshrc' |'.cshrc' |'' | |'.txt' |'.txt' |'' | |'?.txt.txt' |'?.txt' |'.txt' | |'\n.txt.txt' |'\n.txt' |'.txt' | |'\t.txt.txt' |'\t.txt' |'.txt' | |'a b.txt.txt' |'a b.txt' |'.txt' | |'a*b.txt.txt' |'a*b.txt' |'.txt' | |'a?b.txt.txt' |'a?b.txt' |'.txt' | |'a\nb.txt.txt' |'a\nb.txt' |'.txt' | |'a\tb.txt.txt' |'a\tb.txt' |'.txt' | |'txt' |'txt' |'' | |'txt.pdf' |'txt' |'.pdf' | |'txt.tar.gz' |'txt.tar' |'.gz' | |'txt.txt' |'txt' |'.txt' | |---------------|-----------|-------| 

Bandymų rezultatai

Visi testai buvo atlikti.

22
02 дек. Atsakymą pateikė Cyker, gruodžio 2 d. 2016-12-02 12:04 '16 at 12:04 2016-12-02 12:04

Štai keletas alternatyvių pasiūlymų (dažniausiai „ awk ), įskaitant keletą pažangių naudojimo atvejų, pvz., Programinės įrangos paketų versijos numerių išgavimas.

 f='/path/to/complex/file.1.0.1.tar.gz' # Filename : 'file.1.0.x.tar.gz' echo "$f" | awk -F'/' '{print $NF}' # Extension (last): 'gz' echo "$f" | awk -F'[.]' '{print $NF}' # Extension (all) : '1.0.1.tar.gz' echo "$f" | awk '{sub(/[^.]*[.]/, "", $0)} 1' # Extension (last-2): 'tar.gz' echo "$f" | awk -F'[.]' '{print $(NF-1)"."$NF}' # Basename : 'file' echo "$f" | awk '{gsub(/.*[/]|[.].*/, "", $0)} 1' # Basename-extended : 'file.1.0.1.tar' echo "$f" | awk '{gsub(/.*[/]|[.]{1}[^.]+$/, "", $0)} 1' # Path : '/path/to/complex/' echo "$f" | awk '{match($0, /.*[/]/, a); print a[0]}' # or echo "$f" | grep -Eo '.*[/]' # Folder (containing the file) : 'complex' echo "$f" | awk -F'/' '{$1=""; print $(NF-1)}' # Version : '1.0.1' # Defined as 'number.number' or 'number.number.number' echo "$f" | grep -Eo '[0-9]+[.]+[0-9]+[.]?[0-9]?' # Version - major : '1' echo "$f" | grep -Eo '[0-9]+[.]+[0-9]+[.]?[0-9]?' | cut -d. -f1 # Version - minor : '0' echo "$f" | grep -Eo '[0-9]+[.]+[0-9]+[.]?[0-9]?' | cut -d. -f2 # Version - patch : '1' echo "$f" | grep -Eo '[0-9]+[.]+[0-9]+[.]?[0-9]?' | cut -d. -f3 # All Components : "path to complex file 1 0 1 tar gz" echo "$f" | awk -F'[/.]' '{$1=""; print $0}' # Is absolute : True (exit-code : 0) # Return true if it is an absolute path (starting with '/' or '~/' echo "$f" | grep -q '^[/]\|^~/' 

Visais naudojimo atvejais naudojamas originalus pilnas įvesties kelias, nepriklausomai nuo tarpinių rezultatų.

20
16 июня '15 в 12:02 2015-06-16 12:02 atsakymas įteiktas birželio 16 d. 15 val. 12:02 2015-06-16 12:02

Mažiausias ir paprasčiausias sprendimas (vienoje eilutėje) yra:

 $ file=/blaabla/bla/blah/foo.txt echo $(basename ${file%.*}) # foo 
14
22 апр. Atsakymą Ron pateikė balandžio 22 d 2017-04-22 17:39 '17, 17:39 pm 2017-04-22 17:39

[Pataisyta iš vienos eilutės į bendrą bash, elgesys dabar yra suderinamas su dirname ir pagrindinio basename programomis; Pridėta pagrindo.]

Priimtas atsakymas gerai veikia tipiškais atvejais , tačiau jis neveikia kraštų atveju , būtent:

  • Failų pavadinimams be plėtinių (vadinamųjų priesagų likusiai atsakymo daliai) extension=${filename##*.} Grąžina įvesties failo pavadinimą, o ne tuščią eilutę.
  • extension=${filename##*.} neapima pradinio . , prieštaraujant susitarimui.
    • Blindly pridedant . neveiks failų pavadinimų be priesagos.
  • filename="${filename%.*}" Bus tuščia eilutė, jei įvesties failo pavadinimas prasideda . ir jame nėra šių simbolių . (pvz., .bash_profile ) - prieštarauja susitarimui.

---------

Taigi, tvirtas sprendimas, apimantis visus kraštų atvejus, sukelia funkciją - žr. ji gali grąžinti visus kelio komponentus .

Skambinimo pavyzdys:

 splitPath '/etc/bash.bashrc' dir fname fnameroot suffix # -> $dir == '/etc' # -> $fname == 'bash.bashrc' # -> $fnameroot == 'bash' # -> $suffix == '.bashrc' 

Atkreipkite dėmesį, kad argumentai po įvesties kelio yra laisvai parinkti, vietinių kintamųjų pavadinimai.
Norėdami praleisti kintamuosius, kurie nėra svarbūs prieš tuos, kurie yra, nurodykite _ (naudokite kintamąjį metimą $_ ) arba '' ; Pavyzdžiui, norėdami ištraukti šaknies ir failo vardo plėtinį, naudokite splitPath '/etc/bash.bashrc' _ _ fnameroot extension .


 # SYNOPSIS # splitPath path varDirname [varBasename [varBasenameRoot [varSuffix]]] # DESCRIPTION # Splits the specified input path into its components and returns them by assigning # them to variables with the specified *names*. # Specify '' or throw-away variable _ to skip earlier variables, if necessary. # The filename suffix, if any, always starts with '.' - only the *last* # '.'-prefixed token is reported as the suffix. # As with `dirname`, varDirname will report '.' (current dir) for input paths # that are mere filenames, and '/' for the root dir. # As with `dirname` and `basename`, a trailing '/' in the input path is ignored. # A '.' as the very first char. of a filename is NOT considered the beginning # of a filename suffix. # EXAMPLE # splitPath '/home/jdoe/readme.txt' parentpath fname fnameroot suffix # echo "$parentpath" # -> '/home/jdoe' # echo "$fname" # -> 'readme.txt' # echo "$fnameroot" # -> 'readme' # echo "$suffix" # -> '.txt' # --- # splitPath '/home/jdoe/readme.txt' _ _ fnameroot # echo "$fnameroot" # -> 'readme' splitPath() { local _sp_dirname= _sp_basename= _sp_basename_root= _sp_suffix= # simple argument validation (( $# >= 2 )) || { echo "$FUNCNAME: ERROR: Specify an input path and at least 1 output variable name." > exit 2; } # extract dirname (parent path) and basename (filename) _sp_dirname=$(dirname "$1") _sp_basename=$(basename "$1") # determine suffix, if any _sp_suffix=$([[ $_sp_basename = *.* ]]  printf %s ".${_sp_basename##*.}" || printf '') # determine basename root (filemane w/o suffix) if [[ "$_sp_basename" == "$_sp_suffix" ]]; then # does filename start with '.'? _sp_basename_root=$_sp_basename _sp_suffix='' else # strip suffix from filename _sp_basename_root=${_sp_basename%$_sp_suffix} fi # assign to output vars. [[ -n $2 ]]  printf -v "$2" "$_sp_dirname" [[ -n $3 ]]  printf -v "$3" "$_sp_basename" [[ -n $4 ]]  printf -v "$4" "$_sp_basename_root" [[ -n $5 ]]  printf -v "$5" "$_sp_suffix" return 0 } test_paths=( '/etc/bash.bashrc' '/usr/bin/grep' '/Users/jdoe/.bash_profile' '/Library/Application Support/' 'readme.new.txt' ) for p in "${test_paths[@]}"; do echo ----- "$p" parentpath= fname= fnameroot= suffix= splitPath "$p" parentpath fname fnameroot suffix for n in parentpath fname fnameroot suffix; do echo "$n=${!n}" done done 

Bandymo kodas, atliekantis funkciją:

 test_paths=( '/etc/bash.bashrc' '/usr/bin/grep' '/Users/jdoe/.bash_profile' '/Library/Application Support/' 'readme.new.txt' ) for p in "${test_paths[@]}"; do echo ----- "$p" parentpath= fname= fnameroot= suffix= splitPath "$p" parentpath fname fnameroot suffix for n in parentpath fname fnameroot suffix; do echo "$n=${!n}" done done 

Numatomas rezultatas - atkreipkite dėmesį į ribinius atvejus:

  • failo pavadinimas be priesagos
  • failo pavadinimas pradedant nuo . (nelaikomas priesagos pradžia)
  • įvesties kelias, baigiantis / (trailing / ignored)
  • įvesties kelias, tik failo pavadinimas ( .
  • failo, turinčio daugiau nei . -fiksuotas raktas (tik pastarasis laikomas priesaga):
12
09 авг. atsakymas duotas mklement0 09 rugpjūtis. 2013-08-09 06:45 '13, 06:45 am 2013-08-09 06:45

Manau, kad jei jums reikia tik failo pavadinimo, galite pabandyti:

 FULLPATH=/usr/share/X11/xorg.conf.d/50-synaptics.conf # Remove all the prefix until the "/" character FILENAME=${FULLPATH##*/} # Remove all the prefix until the "." character FILEEXTENSION=${FILENAME##*.} # Remove a suffix, in our case, the filename. This will return the name of the directory that contains this file. BASEDIRECTORY=${FULLPATH%$FILENAME} echo "path = $FULLPATH" echo "file name = $FILENAME" echo "file extension = $FILEEXTENSION" echo "base directory = $BASEDIRECTORY" 

Ir tai viskas = D.

12
29 сент. Atsakymą pateikė Andrew Woolfgang 29 rugsėjis. 2011-09-29 10:26 '11 10:26 am 2011-09-29 10:26

Galite praplėsti, kad būtų rodomi visi laukai ir vėlesni, pridėdami - į lauko numerį.

 NAME=`basename "$FILE"` EXTENSION=`echo "$NAME" | cut -d'.' -f2-` 

Taigi, jei FILE yra eth0.pcap.gz , EXTENSION bus pcap.gz

Naudodami tą pačią logiką, failo pavadinimą taip pat galite gauti naudodami '-', tokiu būdu:

 NAME=`basename "$FILE" | cut -d'.' -f-1` 

Tai net veikia failų pavadinimams, neturintiems plėtinio.

10
10 сент. atsakymas į maciek gajewski 10 rugsėjis 2012-09-10 16:46 '12 at 4:46 2012-09-10 16:46

Taigi, jei aš teisingai supratau, problema yra tai, kaip gauti failo, turinčio kelis plėtinius, pavadinimą ir pilną plėtinį, pvz., stuff.tar.gz .

Jis veikia man:

 fullfile="stuff.tar.gz" fileExt=${fullfile#*.} fileName=${fullfile%*.$fileExt} 

Tai suteiks jums tokius stuff kaip failo pavadinimas ir .tar.gz kaip plėtinys. Jis veikia bet kokiam skaičiui plėtinių, įskaitant 0. Tikiuosi, kad tai padės visiems, kurie turi tą pačią problemą =)

7
09 дек. atsakymas pateikiamas Al3xXx 09 dec. 2011-12-09 22:27 '11, 10:27 pm 2011-12-09 22:27

„Magic File Recognition“

Be daugelio gerų atsakymų į šį klausimą, norėčiau pridėti:

„Linux“ ir kitose „unixen“ programose yra magic komanda, vadinama file kuri atlieka failo tipo aptikimą, analizuodama kai kuriuos pirmuosius failo baitus. Tai labai senas įrankis, kuris iš pradžių buvo naudojamas spausdinimo serveriams (jei nėra sukurtas ... nesu tikras dėl to).

 file myfile.txt myfile.txt: UTF-8 Unicode text file -b --mime-type myfile.txt text/plain 

Standartų plėtinius galima rasti programoje /etc/mime.types (mano „ Debian GNU / Linux“ darbalaukyje. Žr. man file ir man mime.types . Jums gali tekti įdiegti file naudingumo ir mime-support paketus):

 grep $( file -b --mime-type myfile.txt ) </etc/mime.types text/plain asc txt text pot brf srt 

Galite nustatyti funkciją, kad nustatytumėte teisingą plėtinį. Yra nedidelis (netikslus) pavyzdys:

 file2ext() { local _mimetype=$(file -Lb --mime-type "$1") _line _basemimetype case ${_mimetype##*[/.-]} in gzip | bzip2 | xz | z ) _mimetype=${_mimetype##*[/.-]} _mimetype=${_mimetype//ip} _basemimetype=$(file -zLb --mime-type "$1") ;; stream ) _mimetype=($(file -Lb "$1")) [ "${_mimetype[1]}" = "compressed" ]  _basemimetype=$(file -b --mime-type - < <( ${_mimetype,,} -d <"$1")) || _basemimetype=${_mimetype,,} _mimetype=${_mimetype,,} ;; executable ) _mimetype='' _basemimetype='' ;; dosexec ) _mimetype='' _basemimetype='exe' ;; shellscript ) _mimetype='' _basemimetype='sh' ;; * ) _basemimetype=$_mimetype _mimetype='' ;; esac while read -a _line ;do if [ "$_line" == "$_basemimetype" ] ;then [ "$_line[1]" ]  _basemimetype=${_line[1]} || _basemimetype=${_basemimetype##*[/.-]} break fi done </etc/mime.types case ${_basemimetype##*[/.-]} in executable ) _basemimetype='' ;; shellscript ) _basemimetype='sh' ;; dosexec ) _basemimetype='exe' ;; * ) ;; esac [ "$_mimetype" ]  [ "$_basemimetype" != "$_mimetype" ]  printf ${2+-v} $2 "%s.%s" ${_basemimetype##*[/.-]} ${_mimetype##*[/.-]} || printf ${2+-v} $2 "%s" ${_basemimetype##*[/.-]} } 

Ši funkcija gali nustatyti „Bash“ kintamąjį, kuris gali būti naudojamas vėliau:

(Tai įkvėpė teisingas atsakymas @Petesh):

 filename=$(basename "$fullfile") filename="${filename%.*}" file2ext "$fullfile" extension echo "$fullfile -> $filename . $extension" 
7
07 июля '13 в 18:47 2013-07-07 18:47 atsakymą pateikė F. Hauri liepos 7 d. 13 val. 18:47 2013-07-07 18:47

Aš naudoju šį scenarijų

 $ echo "foo.tar.gz"|rev|cut -d"." -f3-|rev foo 
6
22 марта '14 в 15:56 2014-03-22 15:56 atsakymą pateikė Joydip Datta, kovo 22 d., 14 d. 15:56 2014-03-22 15:56
 $ F = "text file.test.txt" $ echo ${F\1/' # EXTENSION echo 'hello.txt' | sed -r 's/(.+)\..+|(.*)/\1\2/' # FILENAME 

Pirmoji eilutė paaiškinta: ji atitinka PATH.EXT arba ANYTHING ir pakeičia ją EXT. Jei sutapo ANYTHING, bet kokia grupė nebus parašyta.

1
16 сент. Blauhirnas atsakė rugsėjo 16 d. 2017-09-16 07:41 '17 at 7:41 am 2017-09-16 07:41

Įkurta daugiausia už @ mklement0 puikiai ir pripildyta atsitiktinių, naudingų batalizmų - taip pat kitų atsakymų į šį / kitus klausimus / „tai darn internetas“ ... aš supakavau viską, šiek tiek suprantamesnę, pakartotinai naudojamą funkciją mano (arba jūsų) .bash_profile , kuri rūpinasi tuo, kas (manau) turėtų būti patikimesnė „ dirname / „ basename versija.

 function path { SAVEIFS=$IFS; IFS="" # stash IFS for safe-keeping, etc. [[ $# != 2 ]]  echo "usage: path <path> <dir|name|fullname|ext>"  return # demand 2 arguments [[ $1 =~ ^(.*/)?(.+)?$ ]]  { # regex parse the path dir=${BASH_REMATCH[1]} file=${BASH_REMATCH[2]} ext=$([[ $file = *.* ]]  printf %s ${file##*.} || printf '') # edge cases for extesionless files and files like ".nesh_profile.coffee" [[ $file == $ext ]]  fnr=$file  ext='' || fnr=${file:0:$((${#file}-${#ext}))} case "$2" in dir) echo "${dir%/*}"; ;; name) echo "${fnr%.*}"; ;; fullname) echo "${fnr%.*}.$ext"; ;; ext) echo "$ext"; ;; esac } IFS=$SAVEIFS } 

Naudojimo pavyzdžiai ...

 SOMEPATH=/path/to.some/.random\ file.gzip path $SOMEPATH dir # /path/to.some path $SOMEPATH name # .random file path $SOMEPATH ext # gzip path $SOMEPATH fullname # .random file.gzip path gobbledygook # usage: -bash <path> <dir|name|fullname|ext> 
1
27 авг. atsakymą pateikė Alex Gray 27 rug. 2013-08-27 05:18 '13, 5:18, 2013-08-27 05:18

Iš pirmiau pateiktų atsakymų, trumpiausias „Onliner“, kuris imituoja Python

 file, ext = os.path.splitext(path) 

Darant prielaidą, kad jūsų failas iš tikrųjų turi plėtinį,

 EXT="${PATH##*.}"; FILE=$(basename "$PATH" .$EXT) 
1
03 янв. atsakymas pateikiamas bendr 2014-01-03 14:14 '14 at 14:14 2014-01-03 14:14

IMHO, geriausias sprendimas jau buvo suteiktas (naudojant korpuso parametrų išplėtimą) ir yra geriausias šiuo metu.

Vis dėlto pridedu šį, kuris paprasčiausiai naudoja kvailų komandą, kuri yra neveiksminga ir kurią niekas neturėtų rimtai naudoti:

 FILENAME=$(echo $FILE | cut -d . -f 1-$(printf $FILE | tr . '\n' | wc -l)) EXTENSION=$(echo $FILE | tr . '\n' | tail -1) 

Добавлено просто для удовольствия :-)

0
ответ дан Bruno BEAUFILS 11 дек. '18 в 5:16 2018-12-11 05:16

Используя пример файла /Users/Jonathan/Scripts/bash/MyScript.sh , этот код:

 MY_EXT=".${0##*.}" ME=$(/usr/bin/basename "${0}" "${MY_EXT}") 

приведет к тому, что ${ME} будет MyScript и ${MY_EXT} равен .sh :