【问题标题】:Bash: read a file line-by-line and process each segment as parameters to other progBash:逐行读取文件并将每个段作为参数处理给其他程序
【发布时间】:2011-11-28 23:39:02
【问题描述】:

我有一些繁重的工作要做,所以 Bash 脚本似乎是一个不错的选择。我是 Bash 新手,这种体验让我有点沮丧。

文件 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脚本会这样操作:

  1. 从 mapfiles.txt 中读取一行
  2. 拆分段
  3. 使用正确的参数顺序调用 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 机器上。这三个家伙得到了同样荒谬的输出。

【问题讨论】:

  • 此处无法重现。寻找错别字。此外,而不是所有的削减只使用read file key log lat。 UPD 查看答案。
  • 在循环中结合ssh的时候,看看这个问题:stackoverflow.com/questions/9393038/…

标签: bash parameters line-by-line


【解决方案1】:

你可以简化很多:

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

【讨论】:

  • 您可以进一步简化它。每个参数不需要单独的变量:while read line; do echo $cmd $line; done &lt; "$input"
【解决方案2】:

使用 GNU Parallel,您可以在一行中完成 + 您可以免费并行完成:

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

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

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

    • 非常感谢。你的评论帮助我找出真正的问题所在。不是 Bash 脚本——我在三个不同的盒子上测试它——是 mapfiles.txt 出了问题。该文件在 Windows 中生成,每行以 ^M 结尾。删除^M后,一切顺利。
    猜你喜欢
    • 1970-01-01
    • 2021-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-16
    • 2014-10-16
    • 1970-01-01
    相关资源
    最近更新 更多