Linux 为什么cat命令不能在脚本中工作

Linux 为什么cat命令不能在脚本中工作,linux,bash,scripting,cat,Linux,Bash,Scripting,Cat,我有下面的脚本,它有一个错误。我正在尝试将所有文件合并成一个大文件。在命令行中,cat命令工作正常,内容被打印到重定向文件中。从脚本上看,它有时可以工作,但另一次不行。我不知道为什么它的行为不正常。请帮忙 #!/bin/bash ### For loop starts ### for D in `find . -type d` do combo=`find $D -maxdepth 1 -type f -name "combo.txt"` cat $comb

我有下面的脚本,它有一个错误。我正在尝试将所有文件合并成一个大文件。在命令行中,cat命令工作正常,内容被打印到重定向文件中。从脚本上看,它有时可以工作,但另一次不行。我不知道为什么它的行为不正常。请帮忙

#!/bin/bash

### For loop starts ###

for D in `find . -type d`
do

        combo=`find $D -maxdepth 1 -type f -name "combo.txt"`
        cat $combo >> bigcombo.tsv

done
下面是bash-x app.sh的输出

++ find . -type d
+ for D in '`find . -type d`'
++ find . -maxdepth 1 -type f -name combo.txt
+ combo=
+ cat
^C
更新: 以下几点对我有用。路径有问题。我仍然不知道是什么问题,所以欢迎回答

#!/bin/bash

### For loop starts ###
rm -rf bigcombo.tsv

for D in `find . -type d`
do

                psi=`find $D -maxdepth 1 -type f -name "*.psi_filtered"`
                # This will give us only the directory path from find result i.e. removing filename.
                directory=$(dirname "${psi}")
                cat $directory"/selectedcombo.txt" >> bigcombo.tsv


done

明显的问题是,您试图
cat
一个不存在的文件

次要问题与效率和正确性有关。最好避免运行两个嵌套循环,尽管将操作分为两个步骤在这里并不雅观;内部循环最多只执行一次。将命令结果捕获到变量中是初学者常见的反模式;通常可以避免只使用一次的变量,并避免用cruft乱扔shell内存(同时解决了缺少引号的多个问题-包含文件或目录名的变量基本上应始终以双引号插入)。重定向最好在任何包含循环之外执行

rm file
while something; do
    another thing >>file
done
将打开、查找到文件末尾、写入和关闭文件的次数与循环运行的次数相同,而

while something; do
    another thing
done >file
只执行一次打开、查找和关闭操作,避免在开始循环之前清除文件。尽管你的脚本可以被重构,完全没有任何循环

find ./*/ -type f -name "*.psi_filtered" -execdir cat selectedcombo.txt \;> bigcombo.tsv

根据您的问题,可能存在包含
combo.txt
但不包含任何
*.psi\u筛选的
文件的目录错误。也许你还想看看,(U&L.SE),(SO),(AskU),等等。
cat
运行良好,考虑到
$combo
的无引号扩展。主要问题是
find
命令并不总是至少查找一个文件。您可能只需要像
find这样的东西-maxdepth 2-键入f-name“combo.txt”-exec cat{}+>bigcombo.tsv
。另外,为什么要使用反勾号和命令替换的“新”形式,即
目录=$(dirname“${psi}”)
directory=$(…)
表单是首选表单,因此加入90年代,停止使用反勾号替换命令;-)i、 e.
psi=`find$D-maxdepth 1-type f-name“*.psi\u filtered”`
应该是
psi=$(find$D-maxdepth 1-type f-name“*.psi\u filtered”)
。祝你好运。我稍后会试试你的答案。但首先,这部分将
查找。/*/
不会使脚本保持静态。我想让它保持活力。其次,它是如何工作的,因为传统的程序员将find的输出分配给一个数组,然后循环遍历该数组并对每个文件进行cat。然而在这里,find似乎会获取所有文件,然后运行cat,尽管它工作正常。我不理解这个评论。我想你想搜索当前目录的子目录,但如果你也想包括当前目录,显然要返回到
find.
等。这并没有使它或多或少“动态”,它只是使用稍微不同的参数运行。“传统”程序员通常不会将静态内容放入只使用一次的变量中,就像我在答案中解释的那样。通常,管道比不必要地将结果捕获到变量中更有效、更惯用。正确地说,“传统”shell脚本根本没有数组变量(它们是
ksh
/Bash扩展)。
find
按顺序处理其谓词,直到其中一个为false或谓词用完为止。
-execdir
谓词切换到
find
正在处理和执行命令的目录(并检查其退出状态以确定谓词是否成功)。命令
cat selectedcombo.txt
将指定文件的内容复制到标准输出,shell在启动
find
之前已将其重定向到文件。如果您来自较低级别的语言,如asm或C,请尽量避免将问题划分为不必要的小部分。一个好的shell编程准则是尽量减少外部进程的数量。如果你有使用支持向量运算的数学工具的经验,那么你的思维方式的转变与你必须学会尽可能利用向量运算的方式大致相似。