总结

总结
find . -iname "*.sh" | sed 's/[.]sh$//'
./backup/samukano/ex04/who_am_i
./backup/samukano/ex05/people
./days/day01/samukano/ex01/print_groups
./days/day01/samukano/ex02/find_sh
./samukano/ex04/who_am_i
./samukano/ex05/people

我只需要

who_am_i
people
...
people

答案1

find . -iname "*.sh" -exec basename {} \; | sed s/\.sh//g 

basename实用程序将从路径中删除所有目录信息(相对或绝对)。

如果需要的话,实用dirname程序会执行相反的操作。

答案2

总结

便携,但不坚固:

find . -type f \( -name "*.sh" -o -name "*.Sh" -o -name "*.sH" -o -name "*.SH" \) |
sed -e 's|^.*/||' -e 's/[.][sS][hH]$//'

健壮,用于解析为以空字符结尾的字符串:

find . -type f -iname "*.sh" -printf "%f\0" | sed -z 's/[.][sS][hH]$//'

内部强大,可能有模棱两可的输出,供查看:

find . -type f -iname "*.sh" -printf "%f\0" | sed -z 's/[.][sS][hH]$/\n/'


完整答案

有很多方法,有些方法比其他方法更强大。此外,您可能想要使用的工具具有重叠的功能,但其中许多工具都不是 POSIX,因此您可能有或没有所需的选项。

此外,任何文件名的目录都可能包含换行符和其他奇怪字符。因此,为了以稳健的方式解析文件名,您需要将它们视为以空字符结尾的字符串。

然后,您可能还是希望将结果打印为以换行符结尾的(即常规)字符串,以便于人类阅读(但可能会产生歧义的输出)。

工具通常支持具有非 POSIX 扩展的空终止字符串。


例如,为了摆脱这些主要问题的完整路径,您可以使用:

  • find . -printf "%f",但你find可能会支持也可能不支持-printf
  • 或者basename;
  • 甚至sed

要剥离,.sh您可以使用:

  • basename path_to_process .sh,但它区分大小写,我猜你使用它-iname是有原因的(注意-iname这不是 POSIX 所要求的);
  • 或者sed(像你做的那样),可以不区分大小写。

这个分析并不详尽。


最强大的、不区分大小写的版本返回以空字符结尾的字符串。这使得输出对于进一步的解析完全可靠:

find . -type f -iname "*.sh" -printf "%f\0" | sed -z 's/[.][sS][hH]$//'

相同,返回人类可读的且可能有歧义的输出:

find . -type f -iname "*.sh" -printf "%f\0" | sed -z 's/[.][sS][hH]$/\n/'

歧义表现如下:

foo
bar

是否有两个脚本:foo.shbar.sh?还是只有一个foo(newline here)bar.sh

如果您不能使用而必须以换行符结尾的字符串sed -z提供输入,情况会变得更加混乱。在这种情况下,单个文件也会生成上述输出。sedfoo.sh(newline here)bar.sh

如果您sed支持-zfind不支持怎么办-printf?也许您的basename支持-z。这应该是完全健全的:

find . -type f -iname "*.sh" -exec basename -z -a {} + | sed -z 's/[.][sS][hH]$//'

或者不支持-a

find . -type f -iname "*.sh" -exec basename -z {} \; | sed -z 's/[.][sS][hH]$//'

我看得出您find确实支持-iname,但也可能不支持。如果没有呢?相当幼稚但有效的方法:

find . -type f \( -name "*.sh" -o -name "*.Sh" -o -name "*.sH" -o -name "*.SH" \) ...

正如您所见,这一切都取决于可用的选项。


最后假设你的路径使用安全设置可打印字符(无换行符等)。此命令应便携的并且足够好:

find . -type f \( -name "*.sh" -o -name "*.Sh" -o -name "*.sH" -o -name "*.SH" \) |
sed -e 's|^.*/||' -e 's/[.][sS][hH]$//'

相关内容