【问题标题】:Segregation of numerical results from a single text file to multiple files in linux在linux中将数值结果从单个文本文件分离到多个文件
【发布时间】:2015-02-09 11:40:56
【问题描述】:

我有这样的数据

#start
#gatherData
*ELEMENT_SHELL
48709       1   50614   50616   50618   50613
48710       1   50613   50618   50608   50609
48711       1   50616   50617   50619   50618
48712       1   50618   50619   50607   50608
48715       1   50589   50590   50620   50615
48716       1   50615   50620   50616   50614
48717       1   50590   50591   50621   50620
48721       1   50623   50625   50626   50622
48722       1   50622   50626   50610   50611
48723       1   50625   50614   50613   50626
*END
$PresentData
$RESULT OF strength
48709  1.0267261e-002
48710  1.0721873e-002
48711  1.1930415e-002
48712  1.2186395e-002
48715  9.7443219e-003
48716  1.0036242e-002
48717  1.1186538e-002
48721  7.9333931e-003
48722  8.6850608e-003
48723  8.9872172e-003

我要做的是首先检查下的所有结果 $力量的结果

第二列中的哪些数字介于 0 和 1e-002 之间,然后基于该搜索在 *ELEMENT_SHELL 和 *END 之间的数字并将完整的行发送到新的文本文件 test1.txt。如果数字在 1e-002 到 1e-003 之间,则到下一个文本文件 test2.txt 并将这个单个文件分成两个不同的文件。 Text1.text 会有

48709       1   50614   50616   50618   50613
48710       1   50613   50618   50608   50609
48711       1   50616   50617   50619   50618
48712       1   50618   50619   50607   50608
48716       1   50615   50620   50616   50614
48717       1   50590   50591   50621   50620

Text2.txt 会有

48721       1   50623   50625   50626   50622
48722       1   50622   50626   50610   50611
48723       1   50625   50614   50613   50626
48715       1   50589   50590   50620   50615

任何专家可以建议使用 SED 或 AWk 的方式吗?我认为最终结果可以很容易地通过管道传输,但是从同一个文件中分离并再次找到它是有问题的。提前致谢

【问题讨论】:

    标签: linux awk sed piping


    【解决方案1】:

    作为基本解决方案,请考虑以下代码:

    [hamadhassan $] cat tri.awk
    #!/usr/bin/gawk -f 
    
    BEGIN{
        load_state=1; 
    }
    
    
    $0=="$RESULT OF strength"{
    #    print "end of load state"
        load_state=0;
    }
    
    load_state==1 && NF==6{
    #    print "storing "$0
        lut[$1]=$0; # store line in look up table:
    }
    
    load_state==0 && NF==2{
        if($2>0.0 && $2<1e-2){
        if($1 in lut){
            print lut[$1] > "Text2.txt";
        }
        }else{
        if($1 in lut){
            print lut[$1] > "Text1.txt";
        }
        }
    
    }
    [hamadhassan $]
    

    给定您的示例输入:

    [hamadhassan $] cat test.in
    #start
    #gatherData
    *ELEMENT_SHELL
    48709       1   50614   50616   50618   50613
    48710       1   50613   50618   50608   50609
    48711       1   50616   50617   50619   50618
    48712       1   50618   50619   50607   50608
    48715       1   50589   50590   50620   50615
    48716       1   50615   50620   50616   50614
    48717       1   50590   50591   50621   50620
    48721       1   50623   50625   50626   50622
    48722       1   50622   50626   50610   50611
    48723       1   50625   50614   50613   50626
    *END
    $PresentData
    $RESULT OF strength
    48709  1.0267261e-002
    48710  1.0721873e-002
    48711  1.1930415e-002
    48712  1.2186395e-002
    48715  9.7443219e-003
    48716  1.0036242e-002
    48717  1.1186538e-002
    48721  7.9333931e-003
    48722  8.6850608e-003
    48723  8.9872172e-003[hamadhassan $]
    

    给出:

    [hamadhassan $] ./tri.awk test.in
    [hamadhassan $] cat Text2.txt
    48715       1   50589   50590   50620   50615
    48721       1   50623   50625   50626   50622
    48722       1   50622   50626   50610   50611
    48723       1   50625   50614   50613   50626
    [hamadhassan $] cat Text1.txt
    48709       1   50614   50616   50618   50613
    48710       1   50613   50618   50608   50609
    48711       1   50616   50617   50619   50618
    48712       1   50618   50619   50607   50608
    48716       1   50615   50620   50616   50614
    48717       1   50590   50591   50621   50620
    [hamadhassan $]
    

    这是在带有 awk 3.1.7 的 CenTOS 6 上。

    【讨论】:

    • 不幸的是它给出了一个错误 ./scr.sh: line 7: BEGIN{: command not found。可能是版本问题,能不能给个修改建议?我正在使用 x86_64 GNU/Linux
    • 结果应该不同,正如我在问题中提到的最后两个突出显示的块,谢谢
    • shebang 必须是文件中的第一件事。确保前面没有空格或换行符 (#!/usr/bin/gawk -f )
    【解决方案2】:

    您可以尝试使用以下命令(假设源文件为txt.txt

    grep "$RESULT OF strength" -A1000 txt.txt | awk '$2>0.01' | cut -f 1 | xargs -I{} grep {} txt.txt | egrep "[0-9]+[[:blank:]]+1[[:blank:]]+" > test1.txt
    
    
    grep "$RESULT OF strength" -A1000 txt.txt | awk '$2<0.01' | cut -f 1 | xargs -I{} grep {} txt.txt | egrep "[0-9]+[[:blank:]]+1[[:blank:]]+" > test2.txt
    

    如果列用空格分隔,则为:

    grep "$RESULT OF strength" -A1000 txt.txt | sed 's/[\s]{2,}/\t/g' | awk '$2>0.01' | cut -f 1 -d' ' | xargs -I{} grep {} txt.txt | egrep "[0-9]+[[:blank:]]+1[[:blank:]]+" > test1.txt
    
    grep "$RESULT OF strength" -A1000 txt.txt | sed 's/[\s]{2,}/\t/g' | awk '$2<0.01' | cut -f 1 -d' ' | xargs -I{} grep {} txt.txt | egrep "[0-9]+[[:blank:]]+1[[:blank:]]+" > test2.txt
    

    【讨论】:

    • 它不会向新文件返回任何内容。
    • 它适用于我的 debian...无论如何,尝试将[[:blank:]] 更改为[ \t] 以防万一...当然,更改txt.txt(所有出现)为您的文件名。 ..
    • 文件又是空的。据我了解,您阅读了“$Result OF strength”下的完整文本,然后对其进行排序..请您解释一下什么是什么?然后我就可以整理出来了。由于它是一个衬里,我不明白它逐行使用它并查看输出。这将非常有帮助。谢谢
    • 是的,该行获取文件“txt.txt”中“$RESULT OF strength”(最多 1000)之后的行,然后获取第二列大于或小于 0.01 的行,然后您只保留 ID(获取剪切的第一列),最后您在完整文件中查找此 ID。
    • 也许问题是字段分隔符...列之间是否有制表符或空格?
    猜你喜欢
    • 1970-01-01
    • 2015-07-30
    • 2020-06-05
    • 1970-01-01
    • 1970-01-01
    • 2015-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多