我想分别获取文件名(不带扩展名)和扩展名。

到目前为止,我找到的最佳解决方案是:

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

这是错误的,因为如果文件名包含多个,它就不起作用。字符。假设我有a.b.js,它会考虑a和b.js而不是a.b和js。

它可以在Python中用

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

但如果可能的话,我不希望仅仅为此启动Python解释器。

有更好的主意吗?


当前回答

这是我在编写Bash脚本时用于查找文件名和扩展名的算法,当名称与大小写冲突时,该脚本会使名称唯一。

#! /bin/bash 

#
# Finds 
# -- name and extension pairs
# -- null extension when there isn't an extension.
# -- Finds name of a hidden file without an extension
# 

declare -a fileNames=(
  '.Montreal' 
  '.Rome.txt' 
  'Loundon.txt' 
  'Paris' 
  'San Diego.txt'
  'San Francisco' 
  )

echo "Script ${0} finding name and extension pairs."
echo 

for theFileName in "${fileNames[@]}"
do
     echo "theFileName=${theFileName}"  

     # Get the proposed name by chopping off the extension
     name="${theFileName%.*}"

     # get extension.  Set to null when there isn't an extension
     # Thanks to mklement0 in a comment above.
     extension=$([[ "$theFileName" == *.* ]] && echo ".${theFileName##*.}" || echo '')

     # a hidden file without extenson?
     if [ "${theFileName}" = "${extension}" ] ; then
         # hidden file without extension.  Fixup.
         name=${theFileName}
         extension=""
     fi

     echo "  name=${name}"
     echo "  extension=${extension}"
done 

测试运行。

$ config/Name\&Extension.bash 
Script config/Name&Extension.bash finding name and extension pairs.

theFileName=.Montreal
  name=.Montreal
  extension=
theFileName=.Rome.txt
  name=.Rome
  extension=.txt
theFileName=Loundon.txt
  name=Loundon
  extension=.txt
theFileName=Paris
  name=Paris
  extension=
theFileName=San Diego.txt
  name=San Diego
  extension=.txt
theFileName=San Francisco
  name=San Francisco
  extension=
$ 

仅供参考:完整的音译程序和更多测试用例可以在这里找到:https://www.dropbox.com/s/4c6m0f2e28a1vxf/avoid-clashes-code.zip?dl=0

其他回答

您可以强制剪切以显示所有字段和后续字段,并将其添加到字段编号。

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

因此,如果FILE为eth0.pcap.gz,则EXTENSION将为pcap.gz

使用相同的逻辑,您还可以使用“-”和cut获取文件名,如下所示:

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

这甚至适用于没有任何扩展名的文件名。

您还可以使用for循环和tr从路径中提取文件名。。。

for x in `echo $path | tr "/" " "`; do filename=$x; done

tr将路径中的所有“/”分隔符替换为空格,从而生成字符串列表,for循环扫描它们,最后一个在文件名变量中。

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

这可以满足文件名中的多个点和空格,但是如果没有扩展名,则返回文件名本身。但易于检查;只需测试文件名和扩展名是否相同。

自然,此方法不适用于.tar.gz文件。然而,这可以分两步处理。如果扩展名是gz,则再次检查是否也有tar扩展名。

这是唯一对我有用的:

path='folder/other_folder/file.js'

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

>> file

这也可以用于字符串插值,但不幸的是,您必须事先设置基数。

首先,获取不带路径的文件名:

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

或者,您可以关注路径的最后一个“/”,而不是“.”即使您有不可预知的文件扩展名,也可以使用:

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

您可能需要检查文档:

在网页“3.5.3外壳参数扩展”部分在bash手册页的“参数扩展”部分