如何区分带后缀和不带后缀的文件名?
How can I distinguish between file names with and without suffix?
我正在写一个bash shell脚本来输出文件名的后缀。
在这种情况下我使用:
sed 's|.*\.||'
所以输出是例如:
png
exe
c
但是如果文件名没有后缀因此没有点怎么办?我的输出应该是 "no suffix",但我不知道如何使用 sed 执行此操作。
编辑
我已经尝试过的:
目录:
abc.x
abc.y
abc
输入:
find . -type f | sed -E 's/^[^.]+$/no suffix/; s/.*\.//'
输出:
x
y
/abc
使用 2 个连续替换:
sed -E 's/^[^.]+$/no suffix/; s/.+\.//'
awk 中的一个。首先是一些未提供的测试material:
$ cat foo
this.foo
that.bar
nothing
awk:
$ awk '{n=split([=11=],a,".");print (n>1?a[n]:"no suffix")}' foo
foo
bar
no suffix
怎么样
sed '/.*\./s///;t;s/.*/no suffix/'
正则表达式匹配带点的行。在这些行上,我们执行替换。如果发生替换,我们就完成了。否则,执行其他替换。
在替换模式中使用空正则表达式使用了先前的模式。如果发生替换,t
命令分支;没有参数,我们分支到脚本的末尾。 (否则,您可以使用 :label
设置标签并使用 tlabel
分支到该标签。)
$ cat file
abc.x
abc.y
abc
$ awk -F'.' '{print (NF>1 ? $NF : "no suffix")}' file
x
y
no suffix
您可以使用 POSIX shell 参数扩展 完成相同的操作,而无需调用单独的实用程序。例如,要测试文件是否包含 '.'
,您可以简单地使用 test
,例如:
[ "$i" = "${i%.*}" ]
见Posix Programmer's Manual - Shell Command Language - Parameter Expansion
如果它测试为 TRUE,则不存在扩展,否则,您可以使用额外的 参数扩展 来获取扩展本身,例如
[ "$i" = "${i%.*}" ] && echo "$i - no suffix" || echo "$i - ${i##*.}"
(注意: 您需要额外的测试来排除 .foo
(例如 dotfiles),但剩下的给你)
将其包装在一个循环中并排除目录文件,您可以测试目录中的每个文件或在循环中使用 read
并将名称列表传递给它。例如,遍历目录中的文件将导致:
...
ftlcdfil.c - c
geany-plugin_build_w_gtk+2.patch - patch
geany-plugins.spec - spec
geany.spec - spec
geany_build_w_gtk+2.patch - patch
getfl - no suffix
gtkw_save_test.txt - txt
gtkwrite-master.zip - zip
helloleap - no suffix
helloleap.c - c
jnl - no suffix
messages - no suffix
opensuse_15.0_1s_delay.svg - svg
...
使用 Perl
/tmp> ls ab*
abc abc.x abc.y
/tmp> perl -e ' print /\./? "$_\n" : "no suffix\n" for(glob("ab*")) '
no suffix
abc.x
abc.y
/tmp>
我正在写一个bash shell脚本来输出文件名的后缀。
在这种情况下我使用:
sed 's|.*\.||'
所以输出是例如:
png
exe
c
但是如果文件名没有后缀因此没有点怎么办?我的输出应该是 "no suffix",但我不知道如何使用 sed 执行此操作。
编辑 我已经尝试过的:
目录:
abc.x
abc.y
abc
输入:
find . -type f | sed -E 's/^[^.]+$/no suffix/; s/.*\.//'
输出:
x
y
/abc
使用 2 个连续替换:
sed -E 's/^[^.]+$/no suffix/; s/.+\.//'
awk 中的一个。首先是一些未提供的测试material:
$ cat foo
this.foo
that.bar
nothing
awk:
$ awk '{n=split([=11=],a,".");print (n>1?a[n]:"no suffix")}' foo
foo
bar
no suffix
怎么样
sed '/.*\./s///;t;s/.*/no suffix/'
正则表达式匹配带点的行。在这些行上,我们执行替换。如果发生替换,我们就完成了。否则,执行其他替换。
在替换模式中使用空正则表达式使用了先前的模式。如果发生替换,t
命令分支;没有参数,我们分支到脚本的末尾。 (否则,您可以使用 :label
设置标签并使用 tlabel
分支到该标签。)
$ cat file
abc.x
abc.y
abc
$ awk -F'.' '{print (NF>1 ? $NF : "no suffix")}' file
x
y
no suffix
您可以使用 POSIX shell 参数扩展 完成相同的操作,而无需调用单独的实用程序。例如,要测试文件是否包含 '.'
,您可以简单地使用 test
,例如:
[ "$i" = "${i%.*}" ]
见Posix Programmer's Manual - Shell Command Language - Parameter Expansion
如果它测试为 TRUE,则不存在扩展,否则,您可以使用额外的 参数扩展 来获取扩展本身,例如
[ "$i" = "${i%.*}" ] && echo "$i - no suffix" || echo "$i - ${i##*.}"
(注意: 您需要额外的测试来排除 .foo
(例如 dotfiles),但剩下的给你)
将其包装在一个循环中并排除目录文件,您可以测试目录中的每个文件或在循环中使用 read
并将名称列表传递给它。例如,遍历目录中的文件将导致:
...
ftlcdfil.c - c
geany-plugin_build_w_gtk+2.patch - patch
geany-plugins.spec - spec
geany.spec - spec
geany_build_w_gtk+2.patch - patch
getfl - no suffix
gtkw_save_test.txt - txt
gtkwrite-master.zip - zip
helloleap - no suffix
helloleap.c - c
jnl - no suffix
messages - no suffix
opensuse_15.0_1s_delay.svg - svg
...
使用 Perl
/tmp> ls ab*
abc abc.x abc.y
/tmp> perl -e ' print /\./? "$_\n" : "no suffix\n" for(glob("ab*")) '
no suffix
abc.x
abc.y
/tmp>