bash - 逐行读取文件时读取bash脚本中文件的最后一行

标签 bash

<分区>

我正在编写一个脚本来从文件中读取命令并执行特定命令。我希望我的脚本适用于单个输入参数或当参数是包含相关参数的文件名时。

除了一个问题,我的下面的代码工作正常,它忽略了文件的最后一行。所以,如果文件如下。

文件.txt

file1
file2

下面发布的脚本只运行 file.txt 的命令

for currentJob in "$@"
do
    if [[ "$currentJob" != *.* ]]  #single file input arg
    then
        echo $currentJob
        serverJobName="$( tr '[A-Z]' '[a-z]' <<< "$currentJob" )"  #Change to lowercase
                                                                   #run cURL job
        curl -o "$currentJob"PisaInterfaces.xml http://www.ebi.ac.uk/msd-srv/pisa/cgi-bin/interfaces.pisa?"$serverJobName"
    else  #file with list of pdbs
        echo "Reading "$currentJob
        while read line; do
            echo "-"$line
            serverJobName="$( tr '[A-Z]' '[a-z]' <<< "$line" )"
            curl -o "$line"PisaInterfaces.xml http://www.ebi.ac.uk/msd-srv/pisa/cgi-bin/interfaces.pisa?"$serverJobName"
        done < "$currentJob"
    fi
done

当然,在 while 循环之后我重复循环内的步骤以使用最后一个文件完成这些命令的地方有明显的解决方法,但这是不可取的,因为我在 while 循环内所做的任何更改都必须在 while 循环之外再次重复。我在网上搜索了一下,找不到任何人问这个确切的问题。我确定它就在那里,但我还没有找到它。

我得到的输出如下。

>testScript.sh file.txt
Reading file.txt
-file1
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  642k    0  642k    0     0   349k      0 --:--:--  0:00:01 --:--:--  492k

我的 bash 版本是 3.2.48

最佳答案

听起来您的输入文件在最后一行之后缺少换行符。当 read 遇到这种情况时,它将变量(在本例中为 $line)设置为最后一行,但随后返回文件结束错误,因此循环不会t 执行最后一行。要解决此问题,您可以在 read 成功时执行循环它将任何内容读入 $line:

...
while read line || [[ -n "$line" ]]; do
    ...

编辑:while 条件中的 || 是所谓的短路 bool 值——它尝试第一个命令(read line),如果成功它跳过第二个 ([[ -n "$line"]]) 并通过循环(基本上,只要 read 成功,它就像您的原始脚本)。如果 read 失败,它会检查第二个命令 ([[ -n "$line"]]) -- 如果 read 将任何内容读入$line 在到达文件末尾之前(即如果文件中有未终止的最后一行),这将成功,因此将 while 条件作为一个整体来考虑成功,循环再运行一次。

在处理完最后一个未终止的行后,它将再次运行测试。这一次,read 将失败(它仍然在文件末尾),并且由于 read 没有将任何内容读入 $line 这时间 [[ -n "$line"]] 测试将失败,因此 while 条件作为一个整体失败并且循环终止.

EDIT2:[[ ]] 是一个 bash 条件表达式——它不是一个常规命令,但它可以用来代替一个。它的主要目的是根据其内部条件决定成功或失败。在这种情况下,如果操作数 ("$line") 为 NONempty,则 -n 测试意味着成功。还有其他测试条件列表here ,以及 test 命令的手册页。

请注意,[[ ... ]] 中的条件表达式与测试命令 [ ... ] 略有不同——参见 BashFAQ #031差异和可用测试列表。它们既不同于带有 (( ... )) 的算术表达式,也完全不同于带有 ( ... )...

关于bash - 逐行读取文件时读取bash脚本中文件的最后一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15485555/

相关文章:

bash - 在 bash 中无需按 ctrl+r 即可触发反向搜索的替代方法

bash - hg log - 如何以相反的顺序显示修订的日期范围?

c - VT100 数字键盘使用修饰符(ctrl/shift/alt)时的转义码

bash - 我可以引用我在 bash 中指定的最后一个路径或文件吗?

bash - 什么都不做的管道

linux - 为非登录用户设置环境变量

linux - 按特定顺序从文件中选择特定行的简单方法

linux - bash 脚本中的自定义参数

bash - 从 Bash 中的字符串中删除回车符和制表符转义序列

linux - 在 bash 脚本中将十进制转换为十六进制