Bash怎么逐行读取一个文件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bash怎么逐行读取一个文件相关的知识,希望对你有一定的参考价值。

参考技术A

  在 Linux、OSX、 *BSD 或者类 Unix 系统下你可以使用 ​​while..do..done 的 bash 循环来逐行读取一个文件。下面跟着我一起来了解一下在 Linux 或类 UNIX 系统下如何使用 KSH 或 BASH shell 逐行读取一个文件吧。

  Bash逐行读取一个文件 方法

  对于 bash、ksh、 zsh 和其他的 shells 语法如下

  while read -r line; do COMMAND; done < input.file

  通过 -r 选项传递给 read 命令以防止阻止解释其中的反斜杠转义符。

  在 read 命令之前添加 IFS= 选项,来防止首尾的空白字符被去掉。

  while IFS= read -r line; do COMMAND_on $line; done < input.file

  这是更适合人类阅读的语法:

  #!/bin/bashinput="/path/to/txt/file"while IFS= read -r vardo echo "$var"done < "$input"

  示例

  下面是一些例子:

  #!/bin/kshfile="/home/vivek/data.txt"while IFS= read linedo # display $line or do somthing with $line echo "$line"done <"$file"

  在 bash shell 中相同的例子:

  #!/bin/bashfile="/home/vivek/data.txt"while IFS= read -r linedo # display $line or do somthing with $line printf '%s\\n' "$line"done <"$file"

  你还可以看看这个更好的:

  #!/bin/bashfile="/etc/passwd"while IFS=: read -r f1 f2 f3 f4 f5 f6 f7do # display fields using f1, f2,..,f7 printf 'Username: %s, Shell: %s, Home Dir: %s\\n' "$f1" "$f7" "$f6"done <"$file"

  示例输出:

  图01:Bash 脚本:读取文件并逐行输出文件Bash 脚本:逐行读取文本文件并创建为 pdf 文件

  我的输入文件如下(faq.txt):

  我的 bash 脚本:

  

  技巧:从 bash 变量中读取

  让我们看看如何在 Debian 或者 Ubuntu Linux 下列出所有安装过的 php 包,请输入:

  示例输出:

  你现在可以从 $list 中看到它们,并安装这些包:

 

  示例输出:

  

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

我有一些肮脏的工作要做,所以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. 参数顺序有什么问题?

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

答案

你可以简化这个:

while read file key log lat
do
  echo "$cmd" "$key" "$log" "$lat" "$file"
done < "$input"
另一答案

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

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

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

另一答案

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

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

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

以上是关于Bash怎么逐行读取一个文件的主要内容,如果未能解决你的问题,请参考以下文章

使用for循环bash脚本逐行读取文件[重复]

用cshell怎么逐行读文件逐行进行处理

在 bash 上逐行读取文件;每一行都包含另一个 unqiue 文件的路径

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

C++中怎么逐行读取数据

delphi中怎么逐行读取文本文件的数据并将每行分别写入指定的不同编辑框