你如何在 bash 中解析文件名?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/49403/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 17:36:11  来源:igfitidea点击:

How do you parse a filename in bash?

bashshellparsingtokenizecut

提问by Nick Pierpoint

I have a filename in a format like:

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

system-source-yyyymmdd.dat

system-source-yyyymmdd.dat

I'd like to be able to parse out the different bits of the filename using the "-" as a delimiter.

我希望能够使用“-”作为分隔符来解析文件名的不同位。

回答by Bobby Hyman

You can use the cut commandto get at each of the 3 'fields', e.g.:

您可以使用cut 命令获取 3 个“字段”中的每一个,例如:

$ echo "system-source-yyyymmdd.dat" | cut -d'-' -f2
source

"-d" specifies the delimiter, "-f" specifies the number of the field you require

“-d”指定分隔符,“-f”指定您需要的字段编号

回答by Colas Nahaboo

A nice and elegant (in my mind :-) using only built-ins is to put it into an array

仅使用内置函数的一个漂亮而优雅的(在我看来 :-) 是将它放入一个数组中

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

Then, you can find the parts in the array...

然后,您可以找到数组中的部分...

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

Caveat: this will not work if the filename contains "strange" characters such as space, or, heaven forbids, quotes, backquotes...

警告:如果文件名包含“奇怪”字符,如空格,或者,天堂禁止,引号,反引号,这将不起作用。

回答by flight

Depending on your needs, awkis more flexible than cut. A first teaser:

根据您的需要,awk比 cut 更灵活。第一个预告片:

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

Problem is that describing awk as 'more flexible' is certainly like calling the iPhone an enhanced cell phone ;-)

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

回答by David

Use the cutcommand.

使用cut命令。

e.g.

例如

echo "system-source-yyyymmdd.dat" | cut -f1 -d'-'

will extract the first bit.

将提取第一位。

Change the value of the -fparameter to get the appropriate parts.

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

Here's a guide on the Cutcommand.

这是剪切命令的指南。

回答by Shannon Nelson

Another method is to use the shell's internal parsing tools, which avoids the cost of creating child processes:

另一种方法是使用shell的内部解析工具,这样可以避免创建子进程的成本:

oIFS=$IFS
IFS=-
file="system-source-yyyymmdd.dat"
set $file
IFS=$oIFS
echo "Source is "

回答by William Pursell

The simplest (and IMO best way) to do this is simply to use read:

最简单的(也是 IMO 最好的方法)就是使用read

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

There are many variations on that theme, many of which are shell dependent:

该主题有许多变体,其中许多与 shell 相关:

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

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