终端查找,目录最后而不是第一个

时间:2013-12-01 18:03:03

标签: bash makefile terminal

我有makefile将JavaScript文件连接在一起,然后通过uglify-js运行该文件以创建.min.js版本。

我目前正在使用此命令查找并连接我的文件

find src/js -type f -name "*.js" -exec cat {} >> ${jsbuild}$@ \;

但是它首先列出了目录中的文件,这很有意义,但我希望它列出.js文件上面上面的src/js个文件避免得到我的undefined JS错误。

无论如何都要这样做或?我有一个谷歌,看到了sort命令和-s find标志,但它在这一点上有点超出我的理解!

[编辑]

最终的解决方案与接受的答案略有不同,但它被标记为已接受,因为它让我得到答案。这是我使用的命令

cat `find src/js -type f -name "*.js" -print0 | xargs -0 stat -f "%z  %N" | sort -n | sed -e "s|[0-9]*\ \ ||"` > public/js/myCleverScript.js

5 个答案:

答案 0 :(得分:4)

可能的解决方案:

  1. 使用find获取文件名和目录深度,即find ... -printf "%d\t%p\n"
  2. 按目录深度排序列表sort -n
  3. 从输出中删除目录深度以仅使用文件名
  4. 试验:

    没有排序:

    $ find folder1/ -depth -type f -printf "%d\t%p\n"
    2   folder1/f2/f3
    1   folder1/file0
    

    排序:

    $ find folder1/ -type f -printf "%d\t%p\n" | sort -n | sed -e "s|[0-9]*\t||"
    folder1/file0
    folder1/f2/f3
    

    您需要的命令如

    cat $(find src/js -type f -name "*.js" -printf "%d\t%p\n" | sort -n | sed -e "s|[0-9]*\t||")>min.js
    

答案 1 :(得分:1)

... MMMMM

find src/js -type f

根本不应该找到任何目录,并且加倍,因为您的目录名称可能不会以“.js”结尾。 “-name”参数周围的括号也是多余的,请尝试删除它们

find src/js -type f -name "*.js" -exec cat {} >> ${jsbuild}$@ \;

答案 2 :(得分:1)

find可以获得已在命令行上展开的第一个目录级别,这会强制执行目录树遍历的顺序。这解决了顶级目录的问题(与Sergey Fedorov已经接受的解决方案不同),但这也应该回答你的问题,并且总是欢迎更多的选择。

使用GNU coreutils ls,您可以在具有--group-directories-first选项的常规文件之前对目录进行排序。从阅读Mac OS X ls manpage看来,目录总是在OS X中分组,你应该放弃选项。

ls -A --group-directories-first -r | tac | xargs -I'%' find '%' -type f -name '*.js' -exec cat '{}' + > ${jsbuild}$@

如果您没有tac命令,则可以使用sed轻松实现该命令。它颠倒了线的顺序。参见GNU sed。{/ p>的info sed tac

tac(){
    sed -n '1!G;$p;h'
}

答案 3 :(得分:0)

我会得到所有文件的列表:

$ find src/js -type f -name "*.js" > list.txt

使用以下ruby脚本按深度排序,即按其中的'/'排序:

sort.rb:
   files=[]; while gets;  files<<$_; end
   files.sort! {|a,b| a.count('/') <=> b.count('/')}
   files.each {|f| puts f}

像这样:

$ ruby sort.rb < list.txt > sorted.txt

连接它们:

$ cat sorted.txt | while read FILE; do cat "$FILE" >> output.txt; done 

(所有这些都假定您的文件名不包含换行符。)

修改

我的目标是明确。如果你想要简洁,你绝对可以将它浓缩为:

find src/js -name '*.js'| ruby -ne 'BEGIN{f=[];}; f<<$_; END{f.sort!{|a,b| a.count("/") <=> b.count("/")}; f.each{|e| puts e}}' | xargs cat >> concatenated

答案 4 :(得分:0)

你可以这样做......

首先创建一个包含输出文件名称的变量:

OUT="$(pwd)/theLot.js"

然后,将顶级目录中的所有“* .js”放入该文件中:

cat *.js > $OUT

然后让“find”抓取当前目录下的所有其他“* .js”文件:

find . -type d ! -name . -exec sh -c "cd {} ; cat *.js >> $OUT" \;

只是为了解释“查找”命令,它说:

find
.             = starting at current directory
-type d       = all directories, not files
-! -name .    = except the current one
-exec sh -c   = and for each one you find execute the following
"..."         = go to that directory and concatenate all "*.js" files there onto end of $OUT
\;            = and that's all for today, thank you!