Linux新手求助:如何将Bash脚本中basename输出写入文件?
解决Bash脚本批量提取文件名的问题
嗨,很高兴看到你已经搞定了第一个小问题!不过后来的操作失误确实是新手容易踩的坑,我来帮你把问题理清楚:
先说说你之前的正确解法
你用done > list2.txt把整个循环的输出重定向到文件,这个思路是对的——如果把> list2.txt放在循环体里,每次循环都会覆盖文件内容,最后就只剩最后一个文件名;而把重定向放在done后面,是把整个while循环的所有输出一次性写入文件,这就解决了之前“只有单个脚本名”的问题。
为什么修改后list2.txt变成空文件?
你把cat list1.txt | while read LINE改成> list1.txt | while read LINE,这是个典型的新手失误:
> list1.txt不是读取文件的命令,它的作用是清空list1.txt并打开它作为输出目标,管道左边没有任何实际的输出内容,所以while循环根本读不到任何行,自然list2.txt就是空的了。
更高效的优化方案(省掉中间文件list1.txt)
其实你完全可以跳过生成list1.txt这一步,直接让find的结果传给循环处理,一步到位:
find /home/users/code -type f -name "*.sh" | while IFS= read -r LINE; do basename --suffix=".sh" "${LINE}" done > list2.txt
这里加IFS= read -r LINE是为了处理带空格、制表符或者特殊字符的文件名,避免出现意外问题。
另外,还有更简洁的写法,不用while循环,直接用find的-exec参数:
find /home/users/code -type f -name "*.sh" -exec basename --suffix=".sh" {} \; > list2.txt
或者用find自带的格式化输出配合sed去掉后缀,效率更高:
find /home/users/code -type f -name "*.sh" -printf "%f\n" | sed 's/\.sh$//' > list2.txt
%f是find的格式化参数,直接输出不含路径的文件名,再用sed去掉末尾的.sh即可。
内容的提问来源于stack exchange,提问作者bkelly
相关产品推荐
相关产品推荐

