如何在bash中解析文件名?

27

我有一个文件名,格式如下:

system-source-yyyymmdd.dat

我想使用“ - ”作为分隔符来解析文件名的不同部分。

6个回答

32
你可以使用 cut 命令 来获取每个“字段”,例如:
$ echo "system-source-yyyymmdd.dat" | cut -d'-' -f2
source

"-d"指定分隔符,"-f"指定您需要的字段号。


我很好奇你为什么加了 # 提示符。通常,该提示符表示根用户或超级用户。一般来说,我认为像尝试 cut 命令这样的东西最好由普通用户完成。我会使用 $ 提示符。 - Jon Ericson
哦,是的 - 很好的观点。我必须承认,当时我以root身份登录,然后就这么做了 - 我知道这是个坏习惯。话虽如此,我认为echo和cut是最无害的两个命令之一 :) 但是,为了完整起见,我肯定会立即更新示例。干杯。 - Bobby Jack
1
如何将输出赋值给一个变量?如果我执行 var = "system-source-yyyymmdd.dat" | cut -d'-' -f2 是不起作用的。 - EsseTi
1
太棒了 - 3分钟内就得到答案 - 这比打电话问朋友还要快!- 最初作为答案添加,但在我提出问题6年后被删除 :) - Nick Pierpoint

10

我认为一个漂亮而简洁的方法是只使用内置函数将其放入数组中。

var='system-source-yyyymmdd.dat'
parts=(${var//-/ })

然后,您可以在数组中找到那些部分...

echo ${parts[0]}  ==> system
echo ${parts[1]}  ==> source
echo ${parts[2]}  ==> yyyymmdd.dat

注意:如果文件名包含空格、引号或者反引号等“奇怪”的字符,此方法将无法生效……


8

根据您的需求,awk比cut更加灵活。以下是一个简单的示例:

# echo "system-source-yyyymmdd.dat" \
    |awk -F- '{printf "System: %s\nSource: %s\nYear: %s\nMonth: %s\nDay: %s\n",
              $1,$2,substr($3,1,4),substr($3,5,2),substr($3,7,2)}'
System: system
Source: source
Year: yyyy
Month: mm
Day: dd

问题在于将awk描述为“更加灵活”肯定就像称iPhone为增强型手机一样;-)

7
使用cut命令。 例如:
echo "system-source-yyyymmdd.dat" | cut -f1 -d'-'

将提取第一位。

更改-f参数的值以获取适当的部分。

这里有一个关于Cut命令的指南。


1
另一种方法是使用 shell 的内置解析工具,避免创建子进程的成本:
oIFS=$IFS
IFS=-
file="system-source-yyyymmdd.dat"
set $file
IFS=$oIFS
echo "Source is $2"

0

最简单(也是我认为最好的方法)就是直接使用read

$ IFS=-. read system source date ext << EOF
> foo-bar-yyyymmdd.dat
> EOF
$ echo $system
foo
$ echo $source $date $ext
bar yyyymmdd dat

这个主题有很多变化,其中许多是依赖于 shell 的:

bash$ IFS=-. read system source date ext <<< foo-bar-yyyymmdd.dat

echo "$name" | { IFS=-. read system source date ext
   echo In all shells, the variables are set here...; }
echo but only in some shells do they retain their value here

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接