Bash while 循环调用 Python 脚本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2359896/
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-17 21:43:58  来源:igfitidea点击:

Bash while loop calling a Python script

pythonbashwhile-loop

提问by Morlock

I would like to call a Python script from within a Bash while loop. However, I do not understand very well how to use appropriately the while loop (and maybe variable) syntax of the Bash. The behaviour I am looking for is that, while a file still contains lines (DNA sequences), I am calling a Python script to extract groups of sequences so that another program (dialign2) can align them. Finally, I add the alignments to a result file. Note: I am not trying to iterate over the file. What should I change in order for the Bash while loop to work? I also want to be sure that the while loop will re-check the changing file.txt on each loop. Here is my attempt:

我想从 Bash while 循环中调用 Python 脚本。但是,我不太明白如何适当地使用 Bash 的 while 循环(可能还有变量)语法。我正在寻找的行为是,虽然文件仍然包含行(DNA 序列),但我正在调用 Python 脚本来提取序列组,以便另一个程序 (dialign2) 可以对齐它们。最后,我将对齐添加到结果文件中。注意:我不是要遍历文件。我应该更改什么才能使 Bash while 循环正常工作?我还想确保 while 循环会在每个循环中重新检查不断变化的 file.txt。这是我的尝试:

#!/bin/bash
# Call a python script as many times as needed to treat a text file

c=1
while [ `wc -l file.txt` > 0 ] ; # Stop when file.txt has no more lines
do
    echo "Python script called $c times"
    python script.py # Uses file.txt and removes lines from it
    # The Python script also returns a temp.txt file containing DNA sequences
    c=$c + 1
    dialign -f temp.txt # aligns DNA sequences
    cat temp.fa >>results.txt # append DNA alignements to result file
done

Thanks!

谢谢!

回答by MattH

No idea why you want to do this.

不知道你为什么要这样做。

c=1
while [[ -s file.txt ]] ; # Stop when file.txt has no more lines
do
    echo "Python script called $c times"
    python script.py # Uses file.txt and removes lines from it
    c=$(($c + 1))
done

回答by Joe Koberg

try -gtto eliminate the shell metacharacter >

尝试-gt消除 shell 元字符>

while [ `wc -l  file.txt`  -gt 0 ]
do
    ...
    c=$[c + 1]
done

回答by vezult

The following should do what you say you want:

以下应该做你说你想要的:

#!/bin/bash

c=1
while read line; 
do
    echo "Python script called $c times"
    # $line contains a line of text from file.txt
    python script.py 
    c=$((c + 1))
done < file.txt

However, there is no need to use bash, to iterate over the lines in a file. You can do that quite easily without ever leaving python:

但是,不需要使用 bash 来遍历文件中的行。你可以很容易地做到这一点,而无需离开 python:

myfile = open('file.txt', 'r')

for count, line in enumerate(myfile):
    print '%i lines in file' % (count + 1,)
    # the variable "line" contains the line of text from the file.txt 

    # Do your thing here.

回答by ghostdog74

@OP if you want to loop through a file , just use while read loop. Also, you are not using the variables $c as well as the line. Are you passing each line to your Python script? Or you just calling your Python script whenever a line is encountered? (your script going to be slow if you do that)

@OP 如果你想遍历一个文件,只需使用 while read 循环。此外,您没有使用变量 $c 以及行。您是否将每一行都传递给您的 Python 脚本?或者你只是在遇到一行时调用你的 Python 脚本?(如果你这样做,你的脚本会很慢)

while true
do
    while read -r line
    do
       # if you are taking STDIN in myscript.py, then something must be passed to
       # myscript.py, if not i really don't understand what you are doing.

       echo "$line" | python myscript.py > temp.txt
       dialign -f temp.txt # aligns DNA sequences
       cat temp.txt >>results.txt
    done <"file.txt"
    if [ ! -s "file.txt" ]; break ;fi
done  

Lastly, you could have done everything in Python. the way to iterate "file.txt" in Python is simply

最后,您可以用 Python 完成所有工作。在 Python 中迭代“file.txt”的方法很简单

f=open("file.txt"):
for line in f:
    print "do something with line"
    print "or bring what you have in myscript.py here"
f.close()