Bash:以递归方式查找文件

时间:2017-03-06 18:58:25

标签: bash

我有一组目录:

RUN1 RUN2 RUN3

在每个目录中,我都有文件。 RUN1有:

mod1_1 mod1_2 mod1_3

和RUN2有:

mod2_1 mod2_2 mod2_3

每个文件都有这样的行(这是mod1_1):

8.69e-01 2.59e-01 7.82e-01 4.92e-01
8.69e-01 2.56e-01 7.84e-01 4.95e-01
8.72e-01 2.54e-01 7.83e-01 5.00e-01
8.71e-01 2.53e-01 7.84e-01 5.01e-01
8.73e-01 2.53e-01 7.81e-01 4.99e-01

这是mod1_2:

8.69e-01 2.59e-01 7.82e-01 4.98e-01
8.69e-01 2.56e-01 7.84e-01 4.90e-01
8.72e-01 2.54e-01 7.83e-01 5.00e-01
8.71e-01 2.53e-01 7.84e-01 5.01e-01
8.73e-01 2.53e-01 7.81e-01 4.99e-01

我想创建一个新文件,每个mod文件只包含第4列中最小的数字。例如,假设mod1_1和mod2_1是唯一的文件。我想创建一个新文件,其中包含mod1_1中的第1行和mod2_1中的第2行:

8.69e-01 2.59e-01 7.82e-01 4.92e-01  
8.69e-01 2.56e-01 7.84e-01 4.90e-01

我想为每个RUN目录执行此操作。我试过这个:

#/bin/bash

finddir=$(find -type d -name 'RUN*' | sort) #find the dirs
for i in $finddir; do
        cd $i
        echo $(pwd)
        findfiles=$(find -type f -name 'mod*' | sort -V) #find the files
        echo $findfiles
        for j in $findfiles; do
                s1=$(sort -k3,3 j)
                echo $s1
done

我的问题是sort命令,我不知道如何将结果写入文件。有任何想法吗?

伪代码,以防它有用:

For each directory RUN*
    For each file mod*
        get the minimum value in column 4, save the line that has that value
    End for 
    Write the lines that had the minimum values to a new file
End for

编辑:仍有问题。这是我修改的方式:

#/bin/bash

finddir=$(find -type d -name 'RUN*' | sort) #find the dirs
for i in $finddir; do
        cd $i
        echo $(pwd)
        findfiles=$(find -type f -name 'mod*' | sort -V) #find the files
        for j in $findfiles; do
                s1=$(sort -k 4 -g $j)
                echo -n "$s1"
        done
cd ..
done

我'错误地'错了。这有点好 - 它给了我每行的四个数字 - 但它不会返回每个文件中第4列的最小值的行。另外,我仍然不知道如何将最终结果导出到新文件。

2 个答案:

答案 0 :(得分:1)

对于每个文件1_2~]$ cat 1_2 8.69e-01 2.59e-01 7.82e-01 4.98e-01 8.69e-01 2.56e-01 7.84e-01 4.90e-01 8.72e-01 2.54e-01 7.83e-01 5.00e-01 8.71e-01 2.53e-01 7.84e-01 5.01e-01 8.73e-01 2.53e-01 7.81e-01 4.99e-01

,以下命令应该为您提供该文件第4列中编号最小的行:

sort -k

现在使用~]$ sort -k 4 test | head -1 8.69e-01 2.56e-01 7.84e-01 4.90e-01

head -1

如果没有]$ sort -k 4 1_2 8.69e-01 2.56e-01 7.84e-01 4.90e-01 8.69e-01 2.59e-01 7.82e-01 4.98e-01 8.73e-01 2.53e-01 7.81e-01 4.99e-01 8.72e-01 2.54e-01 7.83e-01 5.00e-01 8.71e-01 2.53e-01 7.84e-01 5.01e-01 ,您应该看到它们按照第4列排序:

#!/bin/bash
resultfile="somefile.txt"
for d in $(find . -type d -name 'RUN*');
do
  find $d -type f -name 'mod*' -exec sort -k4 -g {} \; | head -1 >> "$resultfile"
done

修改

import org.apache.spark.sql.{Row, SparkSession}

答案 1 :(得分:1)

有几个问题: 1.)在sort命令中使用$ j而不是j 2.)在echo上引用变量(有关详细信息,请参阅How do I preserve line breaks when storing a command output to a variable in bash?) 3.)你进入一个目录,但永远不会回去......你可能想回去......

我测试了一个更简单的代码版本(并没有进入目录)并且有效:

#!/bin/bash

findfiles=$(find -type f -name 'mod*' | sort -V) #find the files
for j in $findfiles; do
       echo $j
       s1=$(sort -k 4 -g $j)
       echo "$s1"
 done

注意,我使用了sort -g,因此可以正确处理浮点值,例如:如果您将数据更改为(使用4.95e-02而不是第二行中的4.95e-01):

8.69e-01 2.59e-01 7.82e-01 4.92e-01
8.69e-01 2.56e-01 7.84e-01 4.95e-02
8.73e-01 2.53e-01 7.81e-01 4.99e-01
8.72e-01 2.54e-01 7.83e-01 5.00e-01
8.71e-01 2.53e-01 7.84e-01 5.01e-01

然后没有-g顺序就错了:

 $ cat test.dat | sort -k 4
 8.69e-01 2.59e-01 7.82e-01 4.92e-01
 8.69e-01 2.56e-01 7.84e-01 4.95e-02
 8.73e-01 2.53e-01 7.81e-01 4.99e-01
 8.72e-01 2.54e-01 7.83e-01 5.00e-01
 8.71e-01 2.53e-01 7.84e-01 5.01e-01

使用-g代替,order将处理指数正确:

$ cat test.dat | sort -k 4 -g
8.69e-01 2.56e-01 7.84e-01 4.95e-02
8.69e-01 2.59e-01 7.82e-01 4.92e-01
8.73e-01 2.53e-01 7.81e-01 4.99e-01
8.72e-01 2.54e-01 7.83e-01 5.00e-01
8.71e-01 2.53e-01 7.84e-01 5.01e-01