如何用单行无变量命令处理find输出,去除.sh后缀与路径
解决方法
直接给几个可行的单行命令,按需选择:
方法1:用find + basename(最简洁通用)
find . -type f -iname "*.sh" -exec basename {} .sh \;
basename命令本身就是用来提取文件名、去掉路径的,后面加.sh参数会自动去除结尾的.sh后缀,完美匹配需求。
方法2:用find + awk(适合需要额外文本处理的场景)
find . -type f -iname "*.sh" | awk -F/ '{gsub(/\.sh$/, "", $NF); print $NF}'
-F/把路径按斜杠分割,$NF取最后一段(即文件名),gsub(/\.sh$/, "", $NF)去掉文件名结尾的.sh,最后打印处理后的结果。
方法3:用bash循环+变量替换(仅bash环境可用)
find . -type f -iname "*.sh" | while read -r file; do fname="${file##*/}"; echo "${fname%.sh}"; done
${file##*/}是bash的参数扩展,用来去掉路径部分只留文件名;${fname%.sh}去掉文件名结尾的.sh后缀。
你之前的错误原因:
- 嵌套变量替换报错:
${$(find ...)%.sh}这种写法在ash(比如BusyBox的shell)里不支持嵌套的命令替换+参数扩展,就算在bash里,命令替换返回的多行结果会被合并成一行,这个处理只会作用于最后一行,根本没法正确处理每个文件。 - xargs用法错误:
"${xargs%.sh}" echo是语法错误,xargs是命令不是变量,不能这么用。如果想用xargs,正确写法是find . -type f -iname "*.sh" | xargs -I {} basename {} .sh,用-I {}指定占位符,把每个文件路径传给basename处理。
内容的提问来源于stack exchange,提问作者RaduIoan
相关产品推荐
相关产品推荐

