2011-10-01 28 views
30

我有一些肮脏的工作要做,所以Bash脚本似乎是一个不错的选择。我是Bash新手,经历让我感到沮丧。Bash:逐行读取文件并将每个段作为参数传给其他prog

文件mapfiles.txt由以下几行组成。每行有四个由空格分隔的段。每个片段表示外部程序名称“prog”的输入参数。例如, “cm19_1.png” 是文件名, “0001” 的指数, “121422481” 的经度,而 “31035995” 的纬度

文件:mapfiles.txt

cm19_1.png 0001 121422481 31035995 
cm19_2.png 0002 121423224 31035995 
cm19_3.png 0003 121423967 31035995 
… 

我想要执行类似的命令到每一行。如下所示,prog的输入参数顺序稍有不同。因此编写一个bash脚本来处理重复的工作是有意义的。

[Usage] prog <index> <longitude> <latitude> <filename> 
example: prog 0001 121422481 31035995 cm19_1.png 

通常,bash脚本会以这种方式操作:从mapfiles.txt

  • 拆分

    1. 读取一行段
    2. 呼叫用正确的参数顺序PROG

    这里是run.sh.

    #!/bin/sh 
    
    input=mapfiles.txt 
    cmd=prog 
    
    while read line 
    do 
         file=$(echo $line | cut -d' ' -f1) 
         key=$(echo $line | cut -d' ' -f2) 
         log=$(echo $line | cut -d' ' -f3) 
         lat=$(echo $line | cut -d' ' -f4) 
         echo $cmd $key $log $lat $file 
    done < "$input" 
    

    我的预期是什么

    prog 0001 121422481 31035995 cm19_1.png 
    prog 0002 121423224 31035995 cm19_2.png 
    prog 0003 121423967 31035995 cm19_3.png 
    … 
    

    实际结果我得到的是困惑我

    cm19_1.png21422481 31035995 
    cm19_2.png21423224 31035995 
    cm19_3.png21423967 31035995 
    

    问题

    1. 哪里是 '前卫'?
    2. 白色空间在哪里?
    3. 参数顺序有什么问题?

    嗯......我在我的Mac上用vim编写了这个脚本,并将它复制到Scientific Linux盒子和一个gentoo盒子中。这三个人得到同样荒谬的结果。

  • +1

    不可再生这里。寻找错别字。此外,而不是所有的削减只使用'读取文件密钥日志lat'。 * UPD *查看答案。 –

    +0

    当与循环中的ssh结合使用时,请看一下这个问题:http://stackoverflow.com/questions/9393038/ssh-breaks-out-of-while-loop-in-bash – Christian

    回答

    42

    可以简化这个有很多:

    while read file key log lat 
    do 
        echo "$cmd" "$key" "$log" "$lat" "$file" 
    done < "$input" 
    
    +0

    这是一个不错而优雅的技巧。 –

    +6

    您可以进一步简化它。你不需要为每个参数使用单独的变量:'while read line;做echo $ cmd $ line;完成<“$ input”' – Idelic

    2

    prog可能已经消失了,因为$cmd不出口。您的/ bin/sh版本可能会在单独的shell中执行while语句。这不应该是这样,我的bash安装不是这种情况,但是也许你在这个部门的行为有趣。

    UPD我看到你有几个盒子可以得到相同的结果。这使得子壳理论不太可能。也许你的脚本和/或源文件中有一些有趣的字符。

    我已将您的脚本和您的源文件复制并粘贴到我的gentoo框中,并提供了预期的结果。也许你应该这样做,并将文件与原始文件进行比较。

    +2

    非常感谢。你的评论帮助我找出真正出问题的地方。这不是Bash脚本 - 我在三个不同的盒子上测试它 - 这是出错的mapfiles.txt。该文件在Windows中生成,每行以^ M结尾。删除^ M后,一切顺利。 –

    8

    使用GNU并行,你可以做一个单行+你得到它的并行完成免费:

    cat mapfile.txt | parallel --colsep '\s' prog {2} {3} {4} {1} 
    

    观看介绍视频,以了解更多:http://www.youtube.com/watch?v=OpaiGYxkSuQ

    相关问题