答案1
像这样使用 find/cut 会破坏子目录中的任何文件。在当前目录中尝试ls | cut -d"." -f1
,或者如果有子目录,尝试find * -name "*.sh" | sed "s/.sh$//"
通过新的查找, 会*
扩展到当前目录中的所有条目,因此它可能是(例如find file1.sh dir1 dir2 -name "*.sh"
。通过 sed 的管道,只是将末尾去掉。
答案2
*.sh
假设您想显示当前目录中与模式匹配的名称,不带.sh
后缀:
for name in ./*.sh; do
basename "$name" .sh
done
该basename
实用程序输出作为第一个参数给出的路径名的文件名部分,如果给出第二个参数,则该字符串将从名称末尾删除。上面的循环没有考虑隐名称。
如果您需要递归地执行此操作,那么您可以find
像这样使用:
find . -name '*.sh' -exec basename {} .sh \;
这会basename
调用每个找到的路径名并删除sh
每个路径名的文件名后缀。
如果您使用的是bash
shell,您也可以这样做:
shopt -s nullglob dotglob
shopt -s globstar
for name in ./**/*.sh; do
basename "$name" .sh
done
这设置了一些 shell 选项,以便能够找到隐藏名称 ( dotglob
),以避免在存在时出现循环不匹配 ( nullglob
),并且能够使用**
通配模式 ( globstar
; “递归”匹配)。
使用zsh
shell,你会得到类似的效果
print -rC1 -- ./**/*.sh(DN:r:t)
...其中D
和N
在通配限定符通配模式末尾的dotglob
和shellnullglob
中的效果相同bash
,其中:r
从文件名中删除文件名后缀(r
~“root”,即没有后缀的名称的根)并:t
删除路径名的目录部分(t
〜“tail”,即路径名的尾部)。
要按降序(按名称)对名称进行排序,在zsh
shell 中您可以使用
print -rC1 -- ./**/*.sh(DNOn:r:t)
...其中添加的On
意思是“按名称逆序排列”。
对顶部循环的输出进行排序bash
只需将输出传递给sort -r
:
for name in ./*.sh; do
basename "$name" .sh
done | sort -r
同样的find
命令:
find . -name '*.sh' -exec basename {} .sh \; | sort -r
但请注意,如果任何文件名包含嵌入的换行符,这会给您带来奇怪的结果。