Bash'deki dosya ad─▒n─▒ ve uzant─▒s─▒n─▒ ├ž─▒kar─▒n


Al─▒nan cevaba git


Dosya ad─▒n─▒ (uzant─▒s─▒z) ve uzant─▒y─▒ ayr─▒ ayr─▒ almak istiyorum.

┼×imdiye kadar buldu─čum en iyi ├ž├Âz├╝m:

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

Bu yanl─▒┼čt─▒r, ├ž├╝nk├╝ dosya ad─▒ birden fazla . karakter i├žeriyorsa ├žal─▒┼čmaz . , Sahip oldu─čum, diyelim ise a.b.js , bu dikkate alacakt─▒r a ve b.js yerine a.b ve js .

Python ile kolayca yap─▒labilir.

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

ancak m├╝mk├╝nse bunun i├žin bir Python terc├╝man─▒ ate┼člememeyi tercih ederim.

Daha iyi bir fikrin var m─▒?


1938





2009-06-08




Cevap say─▒s─▒n─▒ say: 30






─░lk ├Ânce, dosya yolunu yolsuz olsun:

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

Alternatif olarak, '' yerine yolun son '/' sine odaklanabilirsiniz. Tahmin edilemeyen dosya uzant─▒lar─▒n─▒z olsa bile hangisi ├žal─▒┼čmal─▒d─▒r:

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

Belgeleri kontrol etmek isteyebilirsiniz:


3275







 ~% FILE="example.tar.gz"
~% echo "${FILE%%.*}"
example
~% echo "${FILE%.*}"
example.tar
~% echo "${FILE#*.}"
tar.gz
~% echo "${FILE##*.}"
gz
 

Daha fazla ayr─▒nt─▒ i├žin Bash k─▒lavuzundaki kabuk parametresi geni┼člemesine bak─▒n .


602







Genellikle uzant─▒y─▒ zaten biliyorsunuzdur, bu nedenle kullanmak isteyebilirsiniz:

 basename filename .extension
 

├ľrne─čin:

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

ve al─▒r─▒z

 filename
 

362







POSIX de─či┼čkenlerinin b├╝y├╝s├╝n├╝ kullanabilirsiniz:

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

Dosya ad─▒n─▒z formda olsayd─▒ , ./somefile.tar.gz o echo ${FILENAME%%.*} zaman a├žg├Âzl├╝l├╝kle en uzun e┼čle┼čmeyi kald─▒raca─č─▒ . ve bo┼č dizeye sahip olaca─č─▒n─▒za dair bir uyar─▒ var.

(Ge├žici bir de─či┼čkenle bunun ├╝zerinde ├žal─▒┼čabilirsiniz:

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

)


Bu site daha fazla a├ž─▒kl─▒yor.

 ${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
 

137







Dosya uzant─▒s─▒ yoksa veya dosya ad─▒ yoksa, bu i┼če yaramaz gibi g├Âr├╝nm├╝yor. ─░┼čte ne kullan─▒yorum; yaln─▒zca builtins kullan─▒r ve daha fazlas─▒n─▒ (ancak hepsini de─čil) patolojik dosya adlar─▒n─▒ kullan─▒r.

 #!/bin/bash
for fullpath in "[email protected]"
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's really the base
        base=".$ext"
        ext=""
    fi

    echo -e "$fullpath:\n\tdir  = \"$dir\"\n\tbase = \"$base\"\n\text  = \"$ext\""
done
 

Ve i┼čte baz─▒ testisler:

$ basename-and-extension.sh / / home / me / / home / me / file /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 / dosya:
    dir = "/ home / me /"
    base = "dosya"
    ext = ""
/home/me/file.tar:
    dir = "/ home / me /"
    base = "dosya"
    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 = ""

68







Kullanabilirsiniz basename .

├ľrnek:

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

Sen hep y├╝r├╝tme ancak e─čer kopar─▒l─▒p, uzant─▒l─▒ basename sa─člamak gerekiyor tar ile -z o zaman uzatma olaca─č─▒n─▒ biliyorum .tar.gz .

Bu istedi─čini yapmal─▒:

 tar -zxvf $1
cd $(basename $1 .tar.gz)
 

43







 pax> echo a.b.js | sed 's/\.[^.]*$//'
a.b
pax> echo a.b.js | sed 's/^.*\.//'
js
 

iyi ├žal─▒┼č─▒yor, bu y├╝zden sadece kullanabilirsiniz:

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

Komutlar, bu arada, a┼ča─č─▒daki gibi ├žal─▒┼č─▒r.

─░├žin komut NAME yerine kullan─▒lan bir "." karakter olmayan herhangi bir say─▒da ard─▒ndan "." hi├žbir ┼čey (yani, nihai her ┼čeyi kald─▒r─▒r, sat─▒r─▒n sonuna kadar karakterlerin "." sat─▒r─▒n sonuna kadar dahil). Bu temelde regex hile kullanarak a├žg├Âzl├╝ olmayan bir ikamedir.

Komutu , sat─▒r─▒n ba┼č─▒ndaki EXTENSION bir karakteri izleyen, herhangi bir say─▒daki karakteri de─či┼čtirir "." (yani, sat─▒r─▒n ba┼člang─▒c─▒ndan son noktaya kadar her ┼čeyi kald─▒r─▒r). Bu, varsay─▒lan eylem olan a├žg├Âzl├╝ bir ikamedir.


32







Mellen bir blog yaz─▒s─▒na yapt─▒─č─▒ yorumda ┼č├Âyle yazar:

Bash kullanarak ${file%.*} , dosya ad─▒n─▒ uzant─▒ olmadan ${file##*.} almak ve uzant─▒y─▒ da yaln─▒z almak da m├╝mk├╝nd├╝r. Yani,

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

Çıktılar:

 filename: thisfile
extension: txt
 

27







Gerek ile rahats─▒z etmek awk ya da sed hatta perl bu basit g├Ârev i├žin. os.path.splitext() Yaln─▒zca parametre geni┼čletmelerini kullanan salt Bash uyumlu bir ├ž├Âz├╝m var.

Referans uygulamas─▒

Dok├╝mantasyon os.path.splitext(path) :

Pathname yolunu (root, ext) ├Âyle bir ├žift olarak b├Âl├╝n root + ext == path ve ext bo┼č veya bir nokta ile ba┼člar ve en fazla bir periyot i├žerir. Temel addaki ├Ânde gelen d├Ânemler dikkate al─▒nmaz; splitext('.cshrc') d├Âner ('.cshrc', '') .

Python kodu:

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

Bash Uygulamas─▒

├ľnde gelen d├Ânemleri onurland─▒rmak

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

├ľnde gelen d├Ânemleri dikkate almamak

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

Testler

Burada, her giri┼čte Python referans uygulamas─▒yla e┼čle┼čmesi gereken Yoksay─▒c─▒ ├Ânc├╝ d├Ânemler uygulamas─▒ i├žin test durumlar─▒ verilmi┼čtir .

 |--------------- | ----------- | -------|
|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' |
|--------------- | ----------- | -------|
 

Test sonu├žlar─▒

B├╝t├╝n testler ge├žti.


26







cut Son iki uzant─▒y─▒ ( ".tar.gz" b├Âl├╝m) kald─▒rmak i├žin komutu kullanabilirsiniz :

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

Clayton Hughes taraf─▒ndan bir yorumda belirtildi─či gibi, bu sorudaki ger├žek ├Ârnek i├žin i┼če yaramayacakt─▒r. Alternatif olarak sed , geni┼čletilmi┼č normal ifadelerle kullanmay─▒ ├Âneriyorum , bunun gibi:

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

Son iki (alfa-say─▒sal) uzant─▒y─▒ ko┼čulsuz olarak kald─▒rarak ├žal─▒┼č─▒r.

[Anders Lindahl'un yorumundan sonra tekrar g├╝ncellendi]


25







awk Yaz─▒l─▒m paketleri i├žin s├╝r├╝m numaralar─▒n─▒ ├ž─▒karmak gibi baz─▒ geli┼čmi┼č kullan─▒m durumlar─▒ da dahil olmak ├╝zere baz─▒ alternatif ├Âneriler (├žo─čunlukla i├žinde ).

 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 '^[/]\|^~/'
 

T├╝m kullan─▒m durumlar─▒, ara sonu├žlara ba─čl─▒ olmadan, orijinal tam yolu giri┼č olarak kullan─▒yor.


21







Kabul edilen cevap tipik durumlarda iyi sonu├ž verir , ancak son durumlarda ba┼čar─▒s─▒z olur , yani:

  • Uzant─▒ i├žermeyen dosya adlar─▒ i├žin (bu yan─▒t─▒n geri kalan─▒nda sonek olarak adland─▒r─▒l─▒r ), extension=${filename##*.} bo┼č bir dize yerine girdi dosya ad─▒n─▒ d├Ând├╝r├╝r.
  • extension=${filename##*.} . konvansiyonun aksine , ilk i├žermez .
    • K├Âr k├Âr├╝ne haz─▒rl─▒k . yapmak sonek olmadan dosya adlar─▒ i├žin i┼če yaramaz.
  • filename="${filename%.*}" giri┼č dosyas─▒ ad─▒ ile ba┼čl─▒yor . ve ba┼čka . karakter i├žermiyorsa (├Âr. .bash_profile ) bo┼č dize olacak - kurallara ayk─▒r─▒.

---------

Bu nedenle, t├╝m kenar kasalar─▒n─▒ kapsayan sa─člam bir ├ž├Âz├╝m├╝n karma┼č─▒kl─▒─č─▒ bir fonksiyon gerektirir - a┼ča─č─▒daki tan─▒mlar─▒ inceleyin; o d├Ânebilirsiniz t├╝m bir yolun bile┼čenlerini .

├ľrnek ├ža─čr─▒:

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

Giri┼č yolundan sonraki arg├╝manlar─▒n serbest├že se├žildi─čini, konumsal de─či┼čken adlar─▒n─▒n oldu─čunu unutmay─▒n .
├ľncekinden daha ├Ânce gelmeyen ilgi olmayan de─či┼čkenleri atlamak i├žin, _ (at─▒lma de─či┼čkeni kullanmak i├žin) belirtin $_ veya '' ; ├Ârne─čin, dosya ad─▒ k├Âk├╝n├╝ ve uzant─▒s─▒n─▒ ├ž─▒karmak i├žin kullan─▒n 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." >&2; 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
 

Fonksiyonu uygulayan test kodu:

 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
 

Beklenen ├ž─▒kt─▒ - kenar durumlar─▒n─▒ not edin:

  • son eki olmayan bir dosya ad─▒
  • bir dosya ad─▒ ba┼člang─▒├ž . ( de─čil kabul sonekin ba┼člang─▒c─▒)
  • biten bir giri┼č yolu / (izler / yok say─▒l─▒r)
  • yaln─▒zca dosya ad─▒ olan bir giri┼č yolu ( . ana yol olarak d├Ând├╝r├╝l├╝r)
  • ├Ânceden belirlenmi┼č bir . i┼čaretten daha fazla olan bir dosya ad─▒ (yaln─▒zca son ek olarak kabul edilir):
 ----- /etc/bash.bashrc
parentpath=/etc
fname=bash.bashrc
fnameroot=bash
suffix=.bashrc
----- /usr/bin/grep
parentpath=/usr/bin
fname=grep
fnameroot=grep
suffix=
----- /Users/jdoe/.bash_profile
parentpath=/Users/jdoe
fname=.bash_profile
fnameroot=.bash_profile
suffix=
----- /Library/Application Support/
parentpath=/Library
fname=Application Support
fnameroot=Application Support
suffix=
----- readme.new.txt
parentpath=.
fname=readme.new.txt
fnameroot=readme.new
suffix=.txt
 

18







En k├╝├ž├╝k ve en basit ├ž├Âz├╝m (tek sat─▒rda):

 $ file=/blaabla/bla/blah/foo.txt
echo $(basename ${file%.*}) # foo
 

17


2017-04-22





Ben sadece dosyan─▒n ad─▒na ihtiyac─▒n─▒z varsa, ┼čunu deneyebilirsiniz:

 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"
 

Ve hepsi bu kadar = D.


12







T├╝m alanlar─▒ ve ard─▒ndan gelenleri - alan numaras─▒na eklemek i├žin kesmeye zorlayabilirsiniz .

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

Yani, DOSYA ise eth0.pcap.gz , GEN─░┼×LETME olacak pcap.gz

Ayn─▒ mant─▒─č─▒ kullanarak, '-' kullanarak dosya ad─▒n─▒ a┼ča─č─▒daki gibi kesilmi┼č olarak da alabilirsiniz:

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

Bu, herhangi bir uzant─▒s─▒ olmayan dosya adlar─▒ i├žin bile ├žal─▒┼č─▒r.


11







Tamam, e─čer do─čru anlarsam, buradaki sorun birden fazla uzant─▒ya sahip bir dosyan─▒n ad─▒n─▒ ve tam uzant─▒s─▒n─▒ nas─▒l elde edece─čimiz, ├Ârn stuff.tar.gz .

Bu benim i├žin ├žal─▒┼č─▒yor:

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

Bu stuff dosya ad─▒ ve .tar.gz uzant─▒s─▒ olarak size verecektir . Bu, 0 da dahil olmak ├╝zere herhangi bir say─▒da uzant─▒ i├žin ├žal─▒┼č─▒r. Bu, ayn─▒ sorunu ya┼čayan herkes i├žin yard─▒mc─▒ olaca─č─▒n─▒ umarsa =)


8







Sihirli dosya tan─▒ma

Bu Stack Overflow sorusu ├╝zerine iyi cevaplar─▒n yan─▒ s─▒ra eklemek istiyorum:

Linux ve di─čer unixen dosyalar─▒nda, ilk dosya bayt─▒n─▒ analiz ederek dosya tipi tespitini yapan sihirli bir komut vard─▒r file . Bu, ba┼člang─▒├žta bask─▒ sunucular─▒ i├žin kullan─▒lan ├žok eski bir ara├žt─▒r (e─čer olu┼čturulmad─▒ysa ... Bundan emin de─čilim).

 file myfile.txt
myfile.txt: UTF-8 Unicode text

file -b --mime-type myfile.txt
text/plain
 

Standart uzant─▒lar─▒ /etc/mime.types ( Debian GNU / Linux masa├╝st├╝mde bulunabilir. Bkz. man file Ve man mime.types . Belki de file yard─▒mc─▒ program─▒ ve mime-support paketleri kurman─▒z gerekir ):

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

Do─čru uzant─▒y─▒ belirlemek i├žin bir bash i┼člevi olu┼čturabilirsiniz . K├╝├ž├╝k (m├╝kemmel de─čil) bir ├Ârnek var:

 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##*[/.-]}
}
 

Bu i┼člev daha sonra kullan─▒labilecek bir Bash de─či┼čkenini ayarlayabilir:

(Bu @Petesh'in do─čru cevab─▒ndan ilham alm─▒┼čt─▒r):

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

echo "$fullfile -> $filename . $extension"
 

7







A┼ča─č─▒daki beti─či kullan─▒yorum

 $ echo "foo.tar.gz"|rev|cut -d"." -f3-|rev
foo
 

6







 $ F = "text file.test.txt"  
$ echo ${F/*./}  
txt  
 

Bu, bir dosya ad─▒nda birden fazla nokta ve bo┼čluk sa─člar, ancak uzant─▒ yoksa, dosya ad─▒n─▒ kendisi d├Ând├╝r├╝r. Olsa kontrol etmek kolay; sadece dosya ad─▒n─▒ ve uzant─▒y─▒ ayn─▒ ┼čekilde test edin.

Do─čal olarak bu y├Ântem .tar.gz dosyalar─▒ i├žin ├žal─▒┼čmaz. Ancak bu iki a┼čamal─▒ bir s├╝re├žte ele al─▒nabilir. Uzant─▒ gz ise, tar katran─▒ olup olmad─▒─č─▒n─▒ g├Ârmek i├žin tekrar kontrol edin.


5







Bal─▒kta dosya ad─▒ ve uzant─▒s─▒ nas─▒l ├ž─▒kar─▒l─▒r :

 function split-filename-extension --description "Prints the filename and extension"
  for file in $argv
    if test -f $file
      set --local extension (echo $file | awk -F. '{print $NF}')
      set --local filename (basename $file .$extension)
      echo "$filename $extension"
    else
      echo "$file is not a valid file"
    end
  end
end
 

Uyar─▒lar: Son noktaya b├Âler, i├žinde noktalar olan dosya adlar─▒ i├žin iyi ├žal─▒┼č─▒r, ancak i├žinde noktalar bulunan uzant─▒lar i├žin iyi de─čildir. A┼ča─č─▒daki ├Ârne─če bak─▒n─▒z.

Kullan─▒m─▒:

 $ split-filename-extension foo-0.4.2.zip bar.tar.gz
foo-0.4.2 zip  # Looks good!
bar.tar gz  # Careful, you probably want .tar.gz as the extension.
 

Bunu yapman─▒n daha iyi yollar─▒ olabilir. Geli┼čtirmek i├žin cevab─▒m─▒ d├╝zenlemek i├žin ├žekinmeyin.


Ba┼ča ├ž─▒kaca─č─▒n─▒z s─▒n─▒rl─▒ bir uzant─▒ k├╝mesi varsa ve hepsini tan─▒yorsan─▒z, ┼čunu deneyin:

 switch $file
  case *.tar
    echo (basename $file .tar) tar
  case *.tar.bz2
    echo (basename $file .tar.bz2) tar.bz2
  case *.tar.gz
    echo (basename $file .tar.gz) tar.gz
  # and so on
end
 

─░lk ├Ârnek olarak bu uyar─▒ya sahip de─čil , ancak her vakay─▒ ele alman─▒z gerekiyor, b├Âylece ka├ž uzant─▒yaca─č─▒n─▒za ba─čl─▒ olarak daha s─▒k─▒c─▒ olabilir.


4







─░┼čte AWK ile kod . Daha basit yap─▒labilir. Ama ben AWK konusunda iyi de─čilim.

 filename$ ls
abc.a.txt  a.b.c.txt  pp-kk.txt
filename$ find . -type f | awk -F/ '{print $2}' | rev | awk -F"." '{$1="";print}' | rev | awk 'gsub(" ",".") ,sub(".$", "")'
abc.a
a.b.c
pp-kk
filename$ find . -type f | awk -F/ '{print $2}' | awk -F"." '{print $NF}'
txt
txt
txt
 

4







Basit├že kullan─▒n ${parameter%word}

Senin durumunda:

 ${FILE%.*}
 

Test etmek istiyorsan─▒z, a┼ča─č─▒daki t├╝m ├žal─▒┼čmalar─▒ yap─▒n ve uzant─▒y─▒ kald─▒r─▒n:

 FILE=abc.xyz; echo ${FILE%.*};
FILE=123.abc.xyz; echo ${FILE%.*};
FILE=abc; echo ${FILE%.*};
 

4


2010-07-12





Dan Bina Petesh sadece dosya ad─▒ gerekiyorsa cevap, hem yol ve uzatma tek bir sat─▒rda elimden edilebilir

 filename=$(basename ${fullname%.*})
 

3


2015-12-04





Basit bir cevap:

POSIX de─či┼čkenleri yan─▒t─▒n─▒ geni┼čletmek i├žin daha ilgin├ž desenler yapabilece─činizi unutmay─▒n. Yani burada ayr─▒nt─▒land─▒r─▒lm─▒┼č durum i├žin, basit├že ┼čunu yapabilirsiniz:

 tar -zxvf $1
cd ${1%.tar.*}
 

Bu .tar'─▒n son olu┼čumunu kesecek. <bir ┼čey> .

Daha genel olarak, son olu┼čumunu kald─▒rmak istiyorsan─▒z. <bir ┼čey> . <bir ┼čey - ba┼čka> o zaman

 ${1.*.*}
 

iyi ├žal─▒┼čmas─▒ gerekir.

Yukar─▒daki cevab─▒n ba─člant─▒s─▒ ├Âl├╝ gibi g├Âr├╝n├╝yor. ─░┼čte TLDP'den do─črudan Bash'de yapabilece─činiz bir dizi string manip├╝lasyonunun harika bir a├ž─▒klamas─▒ .


2







Bo┼č uzant─▒lara da izin vermek istiyorsan─▒z , bulabildi─čim en k─▒sa ┼čey bu:

 echo 'hello.txt' | sed -r 's/.+\.(.+)|.*/\1/' # EXTENSION
echo 'hello.txt' | sed -r 's/(.+)\..+|(.*)/\1\2/' # FILENAME
 

A├ž─▒klanan ilk sat─▒r: PATH.EXT veya ANYTHING ile e┼čle┼čir ve EXT ile de─či┼čtirilir. Bir ┼čey e┼čle┼čirse, ext grubu yakalanmaz.


2







B├╝y├╝k ├Âl├ž├╝de @ mklement0'─▒n m├╝kemmelinden yola ├ž─▒karak ve rastgele, kullan─▒┼čl─▒ temellerden yola ├ž─▒karak - bu / di─čer sorulara / ÔÇťbu lanet internetÔÇŁ e verilen di─čer cevaplara dayanarak ... Hepsini biraz, biraz daha anla┼č─▒l─▒r bir ┼čekilde tamamlad─▒m, yeniden kullan─▒labilir i┼člev benim (ya sizin) i├žin .bash_profile (I d├╝┼č├╝n├╝n) ne ilgilenir daha sa─člam bir s├╝r├╝m├╝ olmal─▒d─▒r dirname / basename / ne varsa ..

 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 extensionless 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
}     
 

Kullan─▒m ├Ârnekleri ...

 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>
 

2







├ľrnek dosya kullanarak /Users/Jonathan/Scripts/bash/MyScript.sh bu kod:

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

${ME} olma MyScript ve ${MY_EXT} olma ile sonu├žlanacakt─▒r .sh :


Senaryo:

 #!/bin/bash
set -e

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

echo "${ME} - ${MY_EXT}"
 

Baz─▒ testler:

 $ ./MyScript.sh 
MyScript - .sh

$ bash MyScript.sh
MyScript - .sh

$ /Users/Jonathan/Scripts/bash/MyScript.sh
MyScript - .sh

$ bash /Users/Jonathan/Scripts/bash/MyScript.sh
MyScript - .sh
 

1







Yukar─▒daki cevaplardan PythonÔÇÖlar─▒ taklit eden en k─▒sa oneliner

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

Dosyan─▒z─▒n ger├žekten bir uzant─▒s─▒ oldu─čunu varsayarsak,

 EXT="${PATH##*.}"; FILE=$(basename "$PATH" .$EXT)
 

1







IMHO'ya en iyi ├ž├Âz├╝m zaten verildi (kabuk parametresi geni┼čletmesi kullan─▒larak) ve ┼ču anda en iyi dereceye sahip olan─▒.

Bununla birlikte, sadece dumbs komutlar─▒n─▒ kullanan, verimli olmayan ve hi├ž kimsenin ciddi ┼čekilde kullanmamas─▒ gerekenleri ekliyorum:

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

Sadece e─člence i├žin eklendi :-)


1







Bu benim i├žin ├žal─▒┼čan tek ┼čey:

 path='folder/other_folder/file.js'

base=${path##*/}
echo ${base%.*}

>> file
 

Bu, dize enterpolasyonunda da kullan─▒labilir, ancak ne yaz─▒k ki, base ├Ânceden ayarlaman─▒z gerekir .


1