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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7619438/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 21:05:28  来源:igfitidea点击:

Bash: read a file line-by-line and process each segment as parameters to other prog

bashparametersline-by-line

提问by Jianwen W.

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.

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

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.

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

File: mapfiles.txt

文件: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.

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

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

Generally, the bash script will operate in this way:

一般bash脚本会这样操作:

  1. Read one line from mapfiles.txt
  2. Split the segments
  3. Call the prog with a correct parameter order
  1. 从 mapfiles.txt 中读取一行
  2. 拆分段
  3. 以正确的参数顺序调用程序

Here comes run.sh.

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?
  1. “编”在哪里?
  2. 白色空间在哪里?
  3. 参数顺序有什么问题?

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.

嗯……我在我的 Mac 上使用 vim 编写了这个脚本,并将它复制到一个 Scientific Linux 机器和一个 gentoo 机器上。这三个家伙得到了同样荒谬的输出。

回答by Mat

You can simplify this a lot:

你可以简化很多:

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

回答by Ole Tange

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

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

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

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

回答by n. 'pronouns' m.

progcould have disappeared because $cmdis not exported. Your version of /bin/sh might execute the whilestatement 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.

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

UPDI 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.

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

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.

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