关于regex:如何在bash中检索文件名或扩展名

how to retrieve filename or extension within bash

本问题已经有最佳答案,请猛点这里访问。

我有一个脚本,它将一些文件系统数据推送到另一个系统。

如果我能告诉自己每个文件实际上是什么"类型"的文件,这将非常方便,因为它将有助于以后的查询。

例如,假设我的脚本正在吐出以下内容:

1
2
3
4
5
/home/myuser/mydata/myfile/data.log
/home/myuser/mydata/myfile/myfile.gz
/home/myuser/mydata/myfile/mod.conf
/home/myuser/mydata/myfile/security
/home/myuser/mydata/myfile/last

最后,我想看看:

1
2
3
4
5
/home/myuser/mydata/myfile/data.log log
/home/myuser/mydata/myfile/myfile.gz gz
/home/myuser/mydata/myfile/mod.conf conf
/home/myuser/mydata/myfile/security security
/home/myuser/mydata/myfile/last last

有一种方法可以用正则表达式和sed来实现这一点,但我想不出来。

有什么建议吗?

编辑:

我需要通过命令行获得这个信息。从目前的答案来看,我显然还没有弄清楚。因此,对于我提供的示例数据,假设所有数据都是通过greps和seds提供的(数据已经是英镑化的)。我需要能够将示例数据通过管道传输到sed/grep/awk/无论什么,以产生所需的结果。


打印最后一个由非字母字符分隔的文件。

1
2
3
4
5
6
awk -F '[^[:alpha:]]' '{ print $0,$NF }'
/home/myuser/mydata/myfile/data.log log
/home/myuser/mydata/myfile/myfile.gz gz
/home/myuser/mydata/myfile/mod.conf conf
/home/myuser/mydata/myfile/security security
/home/myuser/mydata/myfile/last last


这应该对你有用:

1
2
3
4
5
6
7
x='/home/myuser/mydata/myfile/security'
( IFS=[/.] && arr=( $x ) && echo ${arr[@]:(-1):1} )
security

x='/home/myuser/mydata/myfile/data.log'
( IFS=[/.] && arr=( $x ) && echo ${arr[@]:(-1):1} )
log


这将提取斜线或点后的最后一个组件。

1
awk -F '[/.]' '{ print $NF }'

正如其他人已经回答的,要分析文件名:

1
2
3
extension="${full_file_name##*.}"   # BASH and Kornshell/POSIX only
filename=$(basename"$full_file_name")
dirname=$(dirname"$full_file_name")

如果文件名中可能包含空格、制表符或其他奇怪字符,则需要引号。

您还可以测试文件是目录还是文件,还是使用test命令(链接到[)进行链接,以便test -f foo[ -f foo ]相同。

但是,你说:"如果我能告诉自己每个文件实际上是什么类型的文件,那就非常方便了。"

在这种情况下,您可能需要调查file命令。此命令将返回由某种magic文件(传统上在/etc/magic中)确定的文件类型,但较新的实现可以使用用户自己的方案。这可以通过扩展名和文件头中的幻数来判断文件类型,或者通过查看文件中的前几行(在第一行中查找正则表达式^#! .*/bash$)。


要提取文件名路径中的最后一个元素,请执行以下操作:

1
filename=$(path##*/}

要提取文件名中点后的字符:

1
extension=${filename##*.}

但是(我的评论)与其看扩展,不如使用file。见man file