如何在linux bash脚本中逐行处理文件

在shell脚本中逐行读取Linux文本文件的内容非常容易,只要处理一些微妙的问题。以下是如何以安全的方式进行。...

在shell脚本中逐行读取Linux文本文件的内容非常容易,只要处理一些微妙的问题。以下是如何以安全的方式进行。

文件、文本和习惯用法

每种编程语言都有一组习惯用法。这些都是完成一系列常见任务的标准的、不花哨的方法。它们是使用程序员正在使用的语言特性之一的基本方式或默认方式。它们成为程序员心理蓝图工具箱的一部分。

从文件中读取数据、处理循环以及交换两个变量的值等操作都是很好的例子。程序员将至少知道一种方法,以一种通用的或普通的方式来实现他们的目的。也许这就足以满足手头的要求了。或者,他们可能会润色代码,使其更有效或适用于他们正在开发的特定解决方案。但是,让他们掌握积木习语是一个很好的起点。

了解和理解一种语言中的习惯用法也使学习一种新的编程语言变得更容易。了解一种语言是如何构造事物的,并在另一种语言中寻找等价的或最接近的事物,这是一个很好的方法,可以让您了解您已经知道的编程语言和您正在学习的编程语言之间的异同。

从文件中读取行:一行

在Bash中,可以使用命令行上的while循环从文件中读取每一行文本并对其执行操作。我们的文本文件名为“数据.txt“它有一个一年中月份的列表。

January February March . . October November December

我们简单的一句话是:

while read line; do echo $line; done < data.txt

如何在linux bash脚本中逐行处理文件

while循环从文件中读取一行,小程序的执行流传递到循环体。echo命令在终端窗口中写入文本行。当没有更多的行要读取时,读取尝试失败,循环完成。

一个巧妙的技巧是将文件重定向到循环中。在其他编程语言中,您需要打开文件,从中读取,然后在完成后再次关闭它。使用Bash,您可以简单地使用文件重定向,并让shell为您处理所有这些低级内容。

当然,这一行不是很有用。Linux已经提供了cat命令,这正是为我们所做的。我们创建了一个冗长的方法来替换三个字母的命令。但它确实明显地证明了从文件中读取的原则。

在某种程度上,这很管用。假设我们有另一个包含月份名称的文本文件。在此文件中,换行符的转义序列已附加到每一行。我们称之为“data2.txt”

January\n February\n March\n . . October\n November\n December\n

让我们在新文件上用一行字。

while read line; do echo $line; done < data2.txt

如何在linux bash脚本中逐行处理文件

反斜杠转义字符“\”已被丢弃。结果是,每行都附加了一个“n”。Bash将反斜杠解释为转义序列的开始。通常,我们不希望Bash解释它正在阅读的内容。在您自己的代码中,读取一行反斜杠转义序列和所有行,并选择解析或替换自己的代码更方便。

如果我们想对文本行进行任何有意义的处理或解析,我们需要使用脚本。

用脚本从文件中读取行

这是我们的剧本。它叫做“script1.sh”

#!/bin/bash Counter=0 while IFS='' read -r LinefromFile || [[ -n "${LinefromFile}" ]]; do ((Counter++)) echo "Accessing line $Counter: ${LinefromFile}" done < "$1"

我们将一个名为Counter的变量设置为零,然后定义while循环。

while行上的第一个语句是IFS=''。IFS代表内部字段分隔符。它包含Bash用来标识单词边界的值。默认情况下,read命令去掉前导和尾随空格。如果我们想从文件中准确地读取行,我们需要将IFS设置为空字符串。

我们可以在循环外设置一次,就像设置Counter的值一样。但是对于更复杂的脚本,尤其是那些包含许多用户定义函数的脚本,IFS可能被设置为脚本中其他地方的不同值。确保每次while循环迭代时IFS都被设置为空字符串可以保证我们知道它的行为。

我们将把一行文本读入一个名为LinefromFile的变量。我们使用-r(将反斜杠作为普通字符读取)选项来忽略反斜杠。他们会像其他角色一样被对待,不会受到任何特殊待遇。

有两个条件将满足while循环并允许循环体处理文本:

  • read-r LinefromFile:当从文件中成功读取一行文本时,read命令向while发送一个成功信号,while循环将执行流传递给循环体。请注意,read命令需要在文本行的末尾看到换行符,才能将其视为成功的读取。如果文件不是符合POSIX的文本文件,则最后一行可能不包含换行符。如果read命令在换行结束前看到文件结尾标记(EOF),它不会把它当作一个成功的阅读。如果发生这种情况,最后一行文本将不会传递到循环体,也不会被处理。
  • [-n“${LinefromFile}”]:我们需要做一些额外的工作来处理与POSIX不兼容的文件。此比较检查从文件中读取的文本。如果它不是以换行符结束的,这个比较仍然会将成功返回到while循环。这样可以确保任何尾行片段都由循环体处理。

这两个子句由OR逻辑运算符“| |”分隔,这样,如果其中一个子句返回success,则无论是否有换行符,检索到的文本都由循环体处理。

在循环体中,我们将计数器变量递增1,并使用echo将一些输出发送到终端窗口。将显示行号和每行的文本。

我们仍然可以使用重定向技巧将文件重定向到循环中。在本例中,我们将重定向$1,该变量包含传递给脚本的第一个命令行参数的名称。使用这个技巧,我们可以很容易地传入希望脚本处理的数据文件的名称。

将脚本复制并粘贴到编辑器中,并用文件名“script1.sh”保存。使用chmod命令使其可执行。

chmod +x script1.sh

如何在linux bash脚本中逐行处理文件

让我们看看脚本如何处理data2.txt文本文件以及其中包含的反斜杠。

./script1.sh data2.txt

如何在linux bash脚本中逐行处理文件

行中的每个字符都逐字显示。反斜杠不能解释为转义字符。它们被印成普通字符。

将行传递给函数

我们还在把文字回音到屏幕上。在现实的编程场景中,我们可能会对文本行做一些更有趣的事情。在大多数情况下,处理另一个函数中的行的进一步处理是一个很好的编程实践。

我们可以这样做。这是“script2.sh”

#!/bin/bash Counter=0 function process_line() { echo "Processing line $Counter: $1" } while IFS='' read -r LinefromFile || [[ -n "${LinefromFile}" ]]; do ((Counter++)) process_line "$LinefromFile" done < "$1"

我们像以前一样定义计数器变量,然后定义一个名为process\u line()的函数。函数的定义必须出现在脚本中首次调用函数之前。

我们的函数将在while循环的每次迭代中被传递给新读取的文本行。我们可以使用$1变量在函数中访问该值。如果有两个变量传递给函数,我们就可以使用$1和$2访问这些值,以此类推获取更多变量。

while循环基本上是相同的。循环体内部只有一个变化。echo行已被对process\u line()函数的调用所替换。请注意,调用函数时不需要在函数名中使用“()”括号。

保存文本行的变量LinefromFile的名称在传递给函数时用引号括起来。这就迎合了有空格的线条。如果没有引号,函数将第一个单词视为$1,第二个单词视为$2,依此类推。使用引号可以确保将整行文本作为$1处理。请注意,这与保存传递给脚本的相同数据文件的$1不同。

由于计数器已在脚本的主体中声明,而不是在函数中,因此可以在process\line()函数中引用它。

将上述脚本复制或键入到编辑器中,并使用文件名“script2.sh”保存。使用chmod使其可执行:

chmod +x script2.sh

如何在linux bash脚本中逐行处理文件

现在我们可以运行它并传入一个新的数据文件“data3.txt”。它有一个月份列表,一行有很多单词。

January February March . . October November \nMore text "at the end of the line" December

我们的命令是:

./script2.sh data3.txt

如何在linux bash脚本中逐行处理文件

这些行从文件中读取,并逐个传递给process\u line()函数。所有的行都正确显示,包括带有退格、引号和多个单词的奇数行。

积木很有用

有一种思路认为习语必须包含该语言特有的东西。这不是我所认同的信仰。重要的是,它充分利用了语言,易于记忆,并提供了一种可靠而健壮的方法来实现代码中的某些功能。

  • 发表于 2021-04-14 18:17
  • 阅读 ( 365 )
  • 分类:互联网

你可能感兴趣的文章

什么是shell脚本,为什么要使用它

... 如何执行shell脚本?很简单。只需将脚本路径作为参数传递给shell: ...

  • 发布于 2021-03-13 04:53
  • 阅读 ( 247 )

如何使用applescript将bash脚本转换为可单击的应用程序

...为输入运行它。这些特殊的应用程序被称为水滴。下面是如何创建一个: ...

  • 发布于 2021-03-21 09:39
  • 阅读 ( 248 )

在linux中,“bash”是什么意思?

...在这篇短文中,我们将探讨Bash是什么,它做什么,以及如何开始使用它。 ...

  • 发布于 2021-03-28 13:14
  • 阅读 ( 451 )

关于linux中bash for loops的所有知识

... 第一行告诉运行这个程序的人如何运行它(即使用bash解释器)。第二个命令与您在命令行中输入的任何其他命令一样。将该文件另存为hello_世界.sh,然后: ...

  • 发布于 2021-03-29 06:22
  • 阅读 ( 312 )

哪个linux shell最好?比较了5种常见的贝壳

...你的计算机需要一个翻译层。这介于你告诉它做什么和它如何理解之间。 ...

  • 发布于 2021-03-30 18:45
  • 阅读 ( 371 )

如何使用受限shell来限制linux用户可以做什么

...改其目录,您可以控制他们可以访问哪些命令。下面介绍如何在Linux上设置受限shell。 受限炮弹 受限shell不是另一个shell。这是标准外壳的另一种模式。Bash、Korn、Fish和其他shell都可以在受限shell模式下启动。在本文中,我们将...

  • 发布于 2021-03-31 10:57
  • 阅读 ( 386 )

如何使用chsh在linux上更改默认shell

Bash不是唯一的Linux shell。很容易尝试其他的shell,比如非常流行的Zsh。找到一个您喜欢的shell后,使用chsh命令将其设置为默认shell。我们会教你怎么做。 为什么贝壳很重要 shell位于您和操作系统之间。它在终端窗口内提供环境...

  • 发布于 2021-04-02 06:04
  • 阅读 ( 337 )

如何在linux上的bash中设置环境变量

Linux上有多种类型的环境变量。了解如何查看它们,为本地和远程登录创建它们,并使它们在重新启动后仍然有效。 环境变量的工作原理 启动终端窗口及其内部的shell时,会引用一组变量,以确保shell配置正确。这些变量还确...

  • 发布于 2021-04-02 06:44
  • 阅读 ( 220 )

如何在linux上使用at和batch来调度命令

...只想在系统有空闲资源时运行进程,可以使用批处理。 如何安排linux作业 cron守护进程维护它在特定时间运行的作业列表。这些任务和程序按预定时间在后台运行。这为您安排需要重复的任务提供了极大的灵活性。无论您需要...

  • 发布于 2021-04-02 18:33
  • 阅读 ( 185 )

如何在linux上创建别名和shell函数

...才能继续存在。一旦窗口关闭,别名将消失。 那么我们如何使我们的别名永久化呢? .bashrc文件和别名 您可能想知道预打包的别名是在哪里定义的。它位于主文件夹的“.bashrc”文件中。当您启动交互式shell时,将读取此文件并...

  • 发布于 2021-04-03 03:45
  • 阅读 ( 209 )
我的田园猫
我的田园猫

0 篇文章

相关推荐