Bash:逐行读取文件并将每个段作为其他程序的参数进行处理

发布于 2024-12-07 12:56:31 字数 1561 浏览 0 评论 0原文

我有一些脏活儿要做,所以 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. “prog”在哪里?
  2. 空白在哪里?
  3. 参数顺序有什么问题?

嗯……我在 Mac 上使用 vim 编写了这个脚本,并将其复制到 Scientific Linux 盒子和 gentoo 盒子中。这三个人得到了同样荒谬的输出。

I have some dirty work to do, so a Bash script seems to be a good choice. I'm new to Bash, and the experience makes me kind of frustrated.

The file mapfiles.txt consists of lines as follow. Each line has four segments separated by a white space. Each segment represents a input parameter to an external program name 'prog'. For example, "cm19_1.png" is the filename, "0001" the index, "121422481" the longitude, and "31035995" the latitude.

File: mapfiles.txt

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

I want to execute similar commands to each line. As show below, the prog's input parameter order is slightly different. So it makes sense to write a bash script to handle the repeated work.

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

Generally, the bash script will operate in this way:

  1. Read one line from mapfiles.txt
  2. Split the segments
  3. Call the prog with a correct parameter order

Here comes 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"

What I expected is

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

The ACTUAL result I got is

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

Problems that confused me

  1. Where is 'prog'?
  2. Where is the white space?
  3. What's wrong with the parameter order?

Hmm… I wrote this script on my Mac using vim and copy it to a Scientific Linux box and a gentoo box. These three guys get the same ridiculous outputs.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

晨敛清荷 2024-12-14 12:56:32

你可以简化很多:

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

You can simplify this a lot:

while read file key log lat
do
  echo "$cmd" "$key" "$log" "$lat" "$file"
done < "$input"
抽个烟儿 2024-12-14 12:56:32

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

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

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

Using GNU Parallel you can do it in a single line + you get it done in parallel for free:

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

Watch the intro videos to learn more: http://www.youtube.com/watch?v=OpaiGYxkSuQ

我还不会笑 2024-12-14 12:56:32

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

UPD 我发现您有几个框给出了相同的结果。这使得亚壳理论不太可能成立。也许您的脚本和/或源文件中有一些有趣的角色。

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

prog could have disappeared because $cmd is not exported. Your version of /bin/sh might execute the while statement in a separate shell. This should not be the case, and this is not the case for my installation of bash, but perhaps yours behaves in interesting ways in this department.

UPD I see that you have several boxes that give the same results. This makes the subshell theory unlikely. Perhaps you have some funny characters in your script and/or source file.

I have copied and pasted your script and your source file to my gentoo box and it gives the expected results. Perhaps you should do the same, and compare the files with your original ones.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文