逐行读取文件中的行,当读取文件的最后一行bash脚本 [英] Read last line of file in bash script when reading file line by line

查看:148
本文介绍了逐行读取文件中的行,当读取文件的最后一行bash脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写一个脚本来从文件中读取命令并执行特定的命令。我希望我的脚本来无论是单输入参数,或者当一个参数是包含了相关参数的文件名。

I am writing a script to read commands from a file and execute a specific command. I want my script to work for either single input arguments or when an argument is a filename which contains the arguments in question.

我的下面只有一个问题工程code,它忽略了文件的最后一行。因此,如果文件如下所述。

My code below works except for one problem, it ignores the last line of the file. So, if the file were as follows.

file.txt的

file1
file2

下面贴只运行该脚本file.txt的命令

The script posted below only runs the command for 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循环之外再重复。我在网上搜索四周,找不到任何人问这个precise问题。我相信这是在那里,但我还没有发现它。

There is, of course, the obvious work around where after the while loop I repeat the steps for inside the loop to complete those commands with the last file, but this is not desirable as any changes I make inside the while loop must be repeated again outside of the while loop. I have searched around online and could not find anyone asking this precise question. I am sure it is out there, but I have not found it.

我得到的输出如下:

>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

My bash version is 3.2.48

推荐答案

这听起来像你的输入文件丢失文件的最后一行后,换行符。当遇到这种情形,它集(在这种情况下, $行)的变量的最后一行,但随后的回报结束文件中的错误使循环将不会执行该最后一行。要解决这个问题,可以使循环执行,如果成功的的上面写任何东西到 $行

It sounds like your input file is missing the newline character after its last line. When read encounters this, it sets the variable ($line in this case) to the last line, but then returns an end-of-file error so the loop doesn't execute for that last line. To work around this, you can make the loop execute if read succeeds or it read anything into $line:

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

编辑: || 中,而条件是什么所谓的短路布尔 - 它会尝试的第一个命令(在线阅读),并且如果成功它跳过第二( [-n$线]] ),并通过循环变(基本上,只要成功,它运行就像你原来的脚本)。如果失败,它会检查第二个命令( [-n$线]] ) - 如果读任何东西到 $行触及文件结束前(即如果有一个未终止的最后一行中文件),这会成功,因此,而条件作为一个整体被认为已经成功,并且循环运行一次。

the || in the while condition is what's known as a short-circuit boolean -- it tries the first command (read line), and if that succeeds it skips the second ([[ -n "$line" ]]) and goes through the loop (basically, as long as the read succeeds, it runs just like your original script). If the read fails, it checks the second command ([[ -n "$line" ]]) -- if read read anything into $line before hitting the end of file (i.e. if there was an unterminated last line in the file), this'll succeed, so the while condition as a whole is considered to have succeeded, and the loop runs one more time.

这是最后的无端接线路被处理后,它会再次运行测试。这一次,将失败(它仍然在文件末尾),由于没看过任何东西到 $行此时 [-n$线]] 测试将的失败,因此,而条件作为一个整体失败,循环终止。

After that last unterminated line is processed, it'll run the test again. This time, the read will fail (it's still at the end of file), and since read didn't read anything into $line this time the [[ -n "$line" ]] test will also fail, so the while condition as a whole fails and the loop terminates.

EDIT2:在 [[]] 是一个bash有条件的前pression - 这不是一个普通的命令,但它可以代替一个被使用。其主要目的是根据它里面的条件,成功或失败。在这种情况下, -n 测试手段成功,如果操作数($行)非空。还有其他的测试条件列表<一个href=\"http://mywiki.wooledge.org/BashGuide/TestsAndConditionals#Conditional_Blocks_.28if.2C_test_and_.5B.5B.29\">here,以及在为测试手册页命令。

The [[ ]] is a bash conditional expression -- it's not a regular command, but it can be used in place of one. Its primary purpose is to succeed or fail, based on the condition inside it. In this case, the -n test means succeed if the operand ("$line") is NONempty. There's a list of other test conditions here, as well as in the man page for the test command.

请注意,在有条件的前pression [[...]] 是从测试命令微妙的不同 [... ] - 见 BashFAQ#差价031 以及可用的测试列表。而且他们都来自算术前pression与不同((...)),并从子shell完全不同与( ...) ...

Note that a conditional expression in [[ ... ]] is subtly different from a test command [ ... ] -- see BashFAQ #031 for differences and a list of available tests. And they're both different from an arithmetic expression with (( ... )), and completely different from a subshell with( ... )...

这篇关于逐行读取文件中的行,当读取文件的最后一行bash脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆