Başda fayl adını və uzantısını çıxarın

Dosyanın adını (uzadılmadan) və uzantıyı ayrıca almaq istəyirəm.

Mən tapdığım ən yaxşı həll yoludur:

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

Bu səhvdir, çünki fayl adı bir neçə olsa, işləmir . simvol Əgər demək olar ki, abjs , abjs yerinə ab.js hesab edəcək.

Bu Python ilə asanlıqla edilə bilər

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

lakin mən mümkünsə, Python tərcüməçisini bu iş üçün idarə etməməyi xahiş edirəm.

Daha yaxşı fikirlər?

1716
08 июня '09 в 17:00 2009-06-08 17:00 ibz 08 iyun 'da 17: 00-da başlayacaq
@ 36 cavab
  • 1
  • 2

Əvvəlcə fayl adını yolsuz olsun:

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

Bundan əlavə, sonuncu "/" yerinə ". öngörüləməz fayl uzantıları olsa belə çalışmalıdır:

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

Sənədləri yoxlaya bilərsiniz:

2944
08 июня '09 в 17:05 2009-06-08 17:05 Cavab Petesh tərəfindən 08 iyun 09: 09-da saat 17: 05-da verilir
 ~% FILE="example.tar.gz" ~% echo "${FILE%%.*}" example ~% echo "${FILE%.*}" example.tar ~% echo "${FILE#*.}" tar.gz ~% echo "${FILE##*.}" gz 
border=0

Ətraflı məlumat üçün, Bash təlimatında kabuk parametrlərinin genişləndirilməsinə baxın.

527
08 июня '09 в 17:05 2009-06-08 17:05 Cavab Juliano tərəfindən 08 iyun '09 saat 17:05 'də verildi. 2009-06-08 17:05

Adətən uzadımı bilirsiniz, buna görə də istifadə edə bilərsiniz:

 basename filename .extension 

məsələn:

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

və almaq

 filename 
306
19 окт. Cavab Tomi Po 19 oktyabr. 2011-10-19 13:56 '11 at 13:56 2011-10-19 13:56

POSIX dəyişənlərin sehrindən istifadə edə bilərsiniz:

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

./somefile.tar.gz forması varsa ./somefile.tar.gz , sonra echo ${FILENAME%%.*} ./somefile.tar.gz echo ${FILENAME%%.*} Ən uzun oyunu ./somefile.tar.gz silmək olacaq . boş bir simli olacaq.

(Müvəqqəti dəyişən ilə bu barədə işləyə bilərsiniz:

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

)


Bu sayt daha çox izah edir.

 ${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 февр. Cavab verilir sotapme 05 feb . 2013-02-05 12:09 '13 at 12:09 2013-02-05 12:09

Faylın heç bir uzadılması və ya fayl adı olmadığı halda bu işləmir. Bu mən istifadə edirəm; yalnız gömülü istifadə edir və patoloji fayl adlarını daha çox (lakin hamısı deyil) idarə edir.

 #!/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 

Və burada bəzi test nümunələri var:

 / bas / home / me / / home / me / file / .hidden.tar / home / me / ... /: dir = "/" baz = "" ext = "" / home / me /: dir = "/ home / me /" baz = "" ext = "" / home / me / file: dir = "/ home / me /" baz = "fayl" ext = "" /home/me/file.tar: dir = "/ home / me /" baz = "fayl" 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 /" baz = ".." ext = "" .: dir = "" base = "." ext = ""
66
10 сент. Cavab Doktor J 10 Sep tərəfindən verilir. 2009-09-10 08:17 '09 saat 08:17 'da 2009-09-10 08:17

Siz əsas istifadə edə bilərsiniz.

Məsələn:

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

Kaldırılacak bir uzantı ilə bir əsas adı -z lazımdır, ancaq, her zaman tar ile -z ile -z , -z bilirsiniz.

Bu, istədiyiniz şeyi etməlidir:

 tar -zxvf $1 cd $(basename $1 .tar.gz) 
42
05 февр. Cavab Bjarke Freund-Hansen tərəfindən verilir 05 fevral. 2013-02-05 11:50 '13 'da 11:50' də 2013-02-05 11:50
 pax> echo abjs | sed 's/\.[^.]*$//' ab pax> echo abjs | sed 's/^.*\.//' js 

yaxşı işləyir, belə ki, istifadə edə bilərsiniz:

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

Komandalar, bu arada, aşağıdakı kimi işləyirlər.

NAME əmri "." Əvəz edir "." hər hansı bir sayda "." deyil "." xəttin sonuna heç bir şey (yəni, hər şey sonuncudan "." dan xəttin sonuna qədər silir) daxildir. Bu, əsasən, müntəzəm ifadələrdən istifadə edərək qeyri-şəffaf bir əvəzdir.

EXTENSION üçün əmr, "." bir xəttin başında, heç bir şey olmadan (yəni, xəttin başlanğıcından sonuna qədər hər şeyi sildikdə). Bu, əvəzolunmaz əvəzdir.

27
08 июня '09 в 17:14 2009-06-08 17:14 Cavab paxdiablo 08 iyun '09 saat 17:14 'da verilir 2009-06-08 17:14

Mellen bir blog yazısında bir şərh yazır:

Bash istifadə edərək, ${file%.*} Uzadılmadan fayl adını və ${file##*.} Uzantıyı özünüz üçün əldə edə bilərsiniz. Yəni

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

Çıxışlar:

 filename: thisfile extension: txt 
26
21 июля '10 в 13:24 2010-07-21 13:24 Kebabbert tərəfindən 21 iyul '13 ' da 13:24 ' də cavab verildi. 2010-07-21 13:24

Son iki ".tar.gz" ( ".tar.gz" ) çıxarmaq üçün cut istifadə edə bilərsiniz:

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

Clayton Hughes şərhdə qeyd edildiyi kimi, bu sözügedən faktiki nümunə üçün işləməyəcək. Buna görə də alternativ olaraq, məsələn, genişləndirilmiş müntəzəm ifadələrlə sed ilə gəlir:

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

Son iki (alfa-numerik) uzantıları heç bir şərt olmadan çıxararaq çalışır.

[Anders Lindal tərəfindən şərhdən sonra yeniləndi]

23
05 февр. Cavab bəzi proqramçı dostum 05 feb tərəfindən verilir . 2013-02-05 11:53 '13 at 11:53 2013-02-05 11:53

Bu sadə tapşırıq üçün awk sed və ya hətta perl haqqında narahatlığa ehtiyac yoxdur. Yalnız parametr genişlənmələrini istifadə edən təmiz bir Bash, os.path.splitext() -component həlli var.

Referans tətbiqi

Sənədlər os.path.splitext(path) :

Yolun (root, ext) root + ext == path və ext boşdur və ya bir dövrdən başlayaraq birdən çox müddət içində yola bölün. Başlanğıcdakı aparıcı dövrlər nəzərə alınmır; splitext('.cshrc') qaytarır ('.cshrc', '') .

Python kodu:

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

Bash tətbiqi

Öncəki dövrlərə riayət etmə

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

Önəmli dövrlərə baxmayaraq

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

Testlər

Aşağıda, hər bir girişdə Python istinadlarının tətbiqinə uyğun olmalıdır ki, aparıcı dövrlərin tətbiq edilməsinə mane olmaq üçün test nümunələri verilmişdir.

 |---------------|-----------|-------| |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 nəticələri

Bütün testlər keçdi.

22
02 дек. Cavab Cyker tərəfindən verilir 02 Dekabr. 2016-12-02 12:04 '16 at 12:04 2016-12-02 12:04

Proqram paketləri üçün versiya nömrələrini çıxarmaq kimi bəzi qabaqcıl istifadə halları da daxil olmaqla bəzi alternativ təkliflər (əsasən awk ).

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

Bütün istifadə hallarda, aralıq nəticələrdən asılı olmayaraq orijinal tam giriş yolundan istifadə olunur.

20
16 июня '15 в 12:02 2015-06-16 12:02 Cavab 16 İyun 2013 tarixində saat 12: 30-da verilir

Ən kiçik və ən sadə həlli (bir xətt) aşağıdakılardır:

 $ file=/blaabla/bla/blah/foo.txt echo $(basename ${file%.*}) # foo 
14
22 апр. Cavab Ron 22 Apr verilir 2017-04-22 17:39 '17 at 17:39 'da 2017-04-22 17:39

[Bir xəttdən ümumi başa düzəlişlər, davranış artıq dirnamebasename kommunalları ilə uyğun gəlir; Bəyanat əlavə edildi.]

Qəbul edilən cavab tipik hallarda yaxşı işləyir , lakin kənar hallarda işləmir , yəni:

  • Uzantıları olmayan fayl adları üçün (cavabın qalan hissəsi üçün əlavə) extension=${filename##*.} Boş simli deyil, giriş faylının adını qaytarır.
  • extension=${filename##*.} başlanğıc daxil deyildir . razılaşmağa zidd.
    • Blindly əlavə . fayl adı üçün əlavə olaraq işləməyəcəkdir.
  • Faylın adı ilə başlayan fayl adı filename="${filename%.*}" Boş bir düstur olacaq . və aşağıdakı simvolları ehtiva etməyib . (məsələn, .bash_profile ) - müqaviləyə zidd.

---------

Beləliklə, bütün kənar vəziyyətləri əhatə edən möhkəm bir həllin mürəkkəbliyi bir funksiyaya səbəb olur - aşağıdakı təsvirinə baxın; yolun bütün komponentlərinə qayıda bilər .

Məsələn nümunə:

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

Giriş yolundan sonra dəlilləri sərbəst şəkildə seçildikdə, mövqelər dəyişənlərinin adları.
Öncədən gələn maraqları olmayan dəyişənləri atlatmaq üçün _ (dəyişən atışdan istifadə edin $_ ) və ya '' ; məsələn kök və fayl adı uzantısını çıxarmaq üçü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." > 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 

Funksiyanı yerinə yetirən 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 

Gözlənilən nəticə - marginal hallara diqqət yetirin:

  • fayl adı əlavə deyil
  • başlayan fayl adı . (sonuncu başlanğıc hesab edilmir)
  • giriş yolunun sona çatması / (arxada qalması / yox sayılması)
  • giriş yolu, yalnız fayl adı (valideyn yolu olaraq qaytarıldı)
  • daha çox olan faylın adı . - təkrarən token (yalnız sonuncu əlavə olaraq hesablanır):
12
09 авг. cavab mklement0 09 aug verilir . 2013-08-09 06:45 '13 saat 06:45 'da 2013-08-09 06:45

Hesab edirəm ki, yalnız fayl adına ehtiyacınız varsa, aşağıdakıları cəhd edə bilərsiniz:

 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" 

Və bu hamısı D.

12
29 сент. Cavab Andrew Woolfgang tərəfindən verilir 29 Sentyabr. 2011-09-29 10:26 '11 saat 10:26 'da 2011-09-29 10:26

Bütün sahələri və sonrakı olanları əlavə etmək üçün məcburi şəkildə kəsmək olar - sahə nömrəsinə.

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

Beləliklə, FILE eth0.pcap.gz ise, EXTENSION pcap.gz olacaq

Eyni məntiqi istifadə edərək, belə bir yarıq ilə '-' istifadə edərək fayl adını da əldə edə bilərsiniz:

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

Bu da bir uzantısı olmayan fayl adları üçün çalışır.

10
10 сент. Cavabına cavab verən maciek gajewski 10 Sep. 2012-09-10 16:46 '12 at 4:46 2012-09-10 16:46

Belə ki, mən düzgün başa stuff.tar.gz , stuff.tar.gz bir neçə uzantı ilə, məsələn, stuff.tar.gz adlı bir adın və tam genişlənmənin necə stuff.tar.gz .

Mənim üçün çalışır:

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

Bu, fayl adı və .tar.gz kimi məsləhətləri genişləndirmək kimi verir. Bu, o cümlədən hər hansı bir sayıda uzantı üçün çalışır. Ümid edirəm ki, bu, eyni problemi olan hər kəsə kömək edəcək =)

7
09 дек. Cavab Al3xXx 09 dek verilir . 2011-12-09 22:27 '11 saat 10:27 'da 2011-12-09 22:27

Sehrli Fayl Tanıma

Bu suala çox yaxşı cavablar əlavə etmək istərdim:

Linux və digər unixen file , faylın ilk növbəsini təhlil edən fayl növü aşkarlayan bir sehrli komanda var. Bu, çap serverləri üçün istifadə edilən çox köhnə bir vasitədir (əgər yaradılmırsa ... Mən bu barədə əmin deyiləm).

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

Standartlara /etc/mime.types ( Debian GNU / Linux masaüstünde, man file baxın ve man mime.types man file baxın. file yardım proqramını ve mime-support paketlerini yüklemeniz tələb oluna bilər):

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

Doğru genişlənməni müəyyən etmək üçün bir funksiyası yarada bilərsiniz. Kiçik (mükəmməl olmayan) bir nümunə 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 funksiya daha sonra istifadə edilə bilən bir Bash dəyişənini təyin edə bilər:

(Bu, düzgün cavab @Petesh ilham olunur):

 filename=$(basename "$fullfile") filename="${filename%.*}" file2ext "$fullfile" extension echo "$fullfile -> $filename . $extension" 
7
07 июля '13 в 18:47 2013-07-07 18:47 Cavab F. Hauri tərəfindən 07.07.2013 18:47 tarixində verilir 2013-07-07 18:47

Aşağıdakı skriptdən istifadə edirəm

 $ echo "foo.tar.gz"|rev|cut -d"." -f3-|rev foo 
6
22 марта '14 в 15:56 2014-03-22 15:56 Cavab Joydip Datta tərəfindən 22 Mart '14 'də saat 15:56' də veriləcək 2014-03-22 15:56
 $ F = "text file.test.txt" $ echo ${F\1/' # EXTENSION echo 'hello.txt' | sed -r 's/(.+)\..+|(.*)/\1\2/' # FILENAME 

1-ci xətt izah edilir: PATH.EXT və ya ANYTHING ilə uyğun gəlir və EXT ilə əvəz olunur. ANYTHING uyğunlaşsa, ek qrupu yazılmayacaq.

1
16 сент. Blauhirn 16 Sentyabrda cavab verdi . 2017-09-16 07:41 '17 də 7:41 'də 2017-09-16 07:41' də

Əsasən xaricində @ mklement0 kənarında təsis edilmiş və təsadüfi, faydalı bashizmlərlə dolu - bu / digər suallara digər cavablar / "ki, darn internet" ... Bir az daha başa düşülmüş, Sizin). .bash_profile , mənim düşündüyüm şeylərə diqqət .bash_profile , daha çox etibarlı dirname / basename versiyası olmalıdır.

 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 } 

İstifadə nümunələri ...

 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 авг. Cavab Alex Gray 27 avqustda verilir. 2013-08-27 05:18 '13 'da 5:18' də 2013-08-27 05:18

Yuxarıdakı cavablardan, Python-u təqlid edən ən qısa oneliner

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

Dosyanızın həqiqətən genişləndiyini nəzərə alaraq,

 EXT="${PATH##*.}"; FILE=$(basename "$PATH" .$EXT) 
1
03 янв. Cavab Jan 03 tarixində ümumi olaraq verilir 2014-01-03 14:14 '14 'da 14:14' də 2014-01-03 14:14

IMHO, ən yaxşı həll artıq verilmişdir (shell parametrlərinin genişləndirilməsi istifadə edərək) və hazırda ən yaxşı.

Bununla yanaşı, sadəcə, səmərəsiz olan və heç kimin ciddi istifadə etməyəcəyi olan dumbs komandanlığı istifadə edən bir əlavə edirəm:

 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 :


Skript:

 #!/bin/bash set -e MY_EXT=".${0##*.}" ME=$(/usr/bin/basename "${0}" "${MY_EXT}") echo "${ME} - ${MY_EXT}" 

Bəzi testlər:

 $ ./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 
0
ответ дан chown 19 мая '12 в 21:59 2012-05-19 21:59

Вот решение sed, которое извлекает компоненты пути в различных формах и может обрабатывать большинство случаев:

 ## Enter the input path and field separator character, for example: ## (separatorChar must not be present in inputPath) inputPath="/path/to/Foo.bar" separatorChar=":" ## sed extracts the path components and assigns them to output variables oldIFS="$IFS" IFS="$separatorChar" read dirPathWithSlash dirPath fileNameWithExt fileName fileExtWithDot fileExt <<<"$(sed -En ' s/^[[:space:]]+// s/[[:space:]]+$// t l1 :l1 s/^([^/]|$)// t s/[/]+$// t l2 :l2 s/^$/filesystem\/\ filesystem/p t h s/^(.*)([/])([^/]+)$/\1\2\ \1\ \3/p g t l3 :l3 s/^.*[/]([^/]+)([.])([a-zA-Z0-9]+)$/\1\ \2\3\ \3/p t s/^.*[/](.+)$/\1/p ' <<<"$inputPath" | tr "\n" "$separatorChar")" IFS="$oldIFS" ## Results (all use separatorChar=":") ## inputPath = /path/to/Foo.bar ## dirPathWithSlash = /path/to/ ## dirPath = /path/to ## fileNameWithExt = Foo.bar ## fileName = Foo ## fileExtWithDot = .bar ## fileExt = bar ## inputPath = /path/to/Foobar ## dirPathWithSlash = /path/to/ ## dirPath = /path/to ## fileNameWithExt = Foobar ## fileName = Foobar ## fileExtWithDot = ## fileExt = ## inputPath = /path/to/...bar ## dirPathWithSlash = /path/to/ ## dirPath = /path/to ## fileNameWithExt = ...bar ## fileName = .. ## fileExtWithDot = .bar ## fileExt = bar ## inputPath = /path/to/..bar ## dirPathWithSlash = /path/to/ ## dirPath = /path/to ## fileNameWithExt = ..bar ## fileName = . ## fileExtWithDot = .bar ## fileExt = bar ## inputPath = /path/to/.bar ## dirPathWithSlash = /path/to/ ## dirPath = /path/to ## fileNameWithExt = .bar ## fileName = .bar ## fileExtWithDot = ## fileExt = ## inputPath = /path/to/... ## dirPathWithSlash = /path/to/ ## dirPath = /path/to ## fileNameWithExt = ... ## fileName = ... ## fileExtWithDot = ## fileExt = ## inputPath = /path/to/Foo. ## dirPathWithSlash = /path/to/ ## dirPath = /path/to ## fileNameWithExt = Foo. ## fileName = Foo. ## fileExtWithDot = ## fileExt = ## inputPath = / (the root directory) ## dirPathWithSlash = filesystem/ ## dirPath = filesystem ## fileNameWithExt = ## fileName = ## fileExtWithDot = ## fileExt = ## inputPath = (invalid because empty) ## dirPathWithSlash = ## dirPath = ## fileNameWithExt = ## fileName = ## fileExtWithDot = ## fileExt = ## inputPath = Foo/bar (invalid because doesn't start with a forward slash) ## dirPathWithSlash = ## dirPath = ## fileNameWithExt = ## fileName = ## fileExtWithDot = ## fileExt = 

İşdə necə:

sed анализирует входной путь и печатает следующие компоненты пути в порядке по отдельным строкам:

  • путь к каталогу с завершающим символом косой черты
  • путь к каталогу без символа конечной косой черты
  • имя файла с расширением
  • имя файла без расширения
  • расширение файла с символом ведущей точки
  • расширение файла без символа ведущей точки

tr преобразует вывод sed в строку с разделителями символов разделителя с указанными выше компонентами пути.

read использует разделительный символ как разделитель полей (IFS = "$ separatorChar" ) и присваивает каждому из компонентов пути свою соответствующую переменную.

Здесь работает конструктор sed :

  • s/^ [[: space:]] +// и s/[[: space:]] + $// листинг любых ведущих и/или завершающие пробельные символы
  • t l1 и : l1 обновляет функцию t для следующей функции s
  • s/^ ([^/] | $)// и t тесты для недопустимого пути ввода (который не начинается с косой черты) в этом случае он оставляет все выходные строки пустыми и завершает команду sed
  • s/[/] + $// удаляет любые завершающие слэши
  • t l2 и : l2 обновляет функцию t для следующей s-функции
  • s/^ $/filesystem/\ [новая строка] файловая система /p и t тесты для специального случая, когда входной путь состоит из корневого каталога /, в в этом случае он выводит файловую систему / и файловую систему для строк dirPathWithSlash и dirPath , оставляет все остальные выходные строки пустыми, и завершает команду sed
  • h сохраняет входной путь в пространстве удержания
  • s/^ (. *) ([/]) ([^/] +) $/\ 1\2\[newline]\1\[newline]\3/p печатает строки dirPathWithSlash , dirPath и fileNameWithExt
  • g извлекает входной путь из пространства удержания
  • t l3 и : l3 обновляет функцию t для следующей s-функции
  • s/^.* [/] ([^/] +) ([.]) ([A-Za-Z0-9] +) $/\ 1\[перевод строки]\2\3\[newline]\3/p и t печатает имя_файла , fileExtWithDot и fileExt вывода для случая, когда существует расширение файла (предполагается, что оно состоит только из буквенно-цифровых символов), а затем завершает команду sed
  • s/^.* [/] (. +) $/\ 1/p выводит имя_файла , но не fileExtWithDot и fileExt для случая, когда расширение файла не существует, а затем завершает команду sed
0
ответ дан scolfax 13 окт. '16 в 8:56 2016-10-13 08:56
  • 1
  • 2

Другие вопросы по меткам или Задайте вопрос