我有一个名为list.txt的文件,如下所示:
input1
input2
input3
我确定最后一行(input3)后面没有空行。然后我有一个python脚本,它将逐行读取该文件,并将文本写入更多文本以创建3个文件(每行一个):
import os
os.chdir("/Users/user/Desktop/Folder")
with open('list.txt','r') as f:
lines = f.read().split('\n')
#for l in lines:
header = "#!/bin/bash \n#BSUB -J %s.sh \n#BSUB -o /scratch/DBC/user/%s.sh.out \n#BSUB -e /scratch/DBC/user/%s.sh.err \n#BSUB -n 1 \n#BSUB -q normal \n#BSUB -P DBCDOBZAK \n#BSUB -W 168:00\n"%(l,l,l)
script = "cd /scratch/DBC/user\n"
script2 = 'grep "input" %s > result.%s.txt\n'%(l,l)
all= "\n".join([header,script,script2])
with open('script_{}.sh'.format(l), 'w') as output:
output.write(all)
我的问题是,这会创建4个文件,而不是3个:script_input1.sh,script_input.sh,script_input3.sh和script_.sh。最后一个文件没有文本,其他文件的input1或input2或input3。
似乎Python逐行读取我的list.txt,但当它到达“input3”时,它会以某种方式继续?如何告诉Python逐行读取我的文件,用“\ n”分隔,但在最后一个文本后停止?
答案 0 :(得分:3)
首先,不要将整个文件读入内存 - 文件是可迭代的,因此逐行读取文件的正确方法是:
with open("/path/to/file.ext") as f:
for line in f:
do_something_with(line)
现在在你的for循环中,你只需要删除该行,如果它是空的,则忽略它:
with open("/path/to/file.ext") as f:
for line in f:
line = line.strip()
if not line:
continue
do_something_with(line)
稍微不相关但Python有多行字符串,因此您不需要连接:
# not sure I got it right actually ;)
script_tpl = """
#!/bin/bash
#BSUB -J {line}.sh
#BSUB -o /scratch/DBC/user/{line}.sh.out
#BSUB -e /scratch/DBC/user/{line}.sh.err
#BSUB -n 1
#BSUB -q normal
#BSUB -P DBCDOBZAK
#BSUB -W 168:00
cd /scratch/DBC/user
grep "input" {line} > result.{line}.txt
"""
with open("/path/to/file.ext") as f:
for line in f:
line = line.strip()
if not line:
continue
script = script_tpl.format(line=line)
with open('script_{}.sh'.format(line), 'w') as output:
output.write(script)
作为最后一点:避免在脚本中更改目录,而是使用os.path.join()
代替绝对路径。
答案 1 :(得分:1)
使用您当前的方法,您需要:
lines
中的最后一个元素是否为空(lines[-1] == ''
)lines = lines[:-1]
)。with open('list.txt','r') as f:
lines = f.read().split('\n')
if lines[-1] == '':
lines = lines[:-1]
for line in lines:
print(line)
不要忘记,文件不以换行符结尾(末尾有一个空行)是合法的......这将处理这种情况。
或者,正如@setsquare指出的那样,您可能想尝试使用readlines()
:
with open('list.txt', 'r') as f:
lines = [ line.rstrip('\n') for line in f.readlines() ]
for line in lines:
print(line)
答案 2 :(得分:1)
您是否考虑过使用readlines()而不是read()?这将让Python为您解决最后一行是否具有\ n的问题。
请记住,如果输入文件在最后一行上有\ n,那么使用read()并按'\ n'分割将创建一个额外的值。例如:
my_string = 'one\ntwo\nthree\n'
my_list = my_string.split('\n')
print my_list
# >> ['one', 'two', 'three', '']
潜在的解决方案
lines = f.readlines()
# remove newlines
lines = [line.strip() for line in lines]
# remove any empty values, just in case
lines = filter(bool, lines)
举一个简单的例子,请看这里:How do I read a file line-by-line into a list?
答案 3 :(得分:1)
f.read()
返回一个以换行符结尾的字符串,split
尽职尽责地将最后一行与空字符串分开。目前尚不清楚为什么要将整个文件明确地读入内存;只是迭代文件对象,让它处理行拆分。
with open('list.txt','r') as f:
for l in f:
# ...
答案 4 :(得分:0)
我认为你使用错误分裂。
如果您有以下内容:
text = 'xxx yyy'
text.split(' ') # or simply text.split()
结果将是
['xxx', 'yyy']
现在,如果你有:
text = 'xxx yyy ' # extra space at the end
text.split()
结果将是
['xxx', 'yyy', '']
,因为分裂得到了每个&之前和之后的内容。 ' (空间)。在这种情况下,在最后一个空格之后有空字符串。
您可能会使用的一些功能:
strip([chars]) # This removes all chars at the beggining or end of a string
示例:
text = '___text_about_something___'
text.strip('_')
结果将是:
'text_about_something'
在您的特定问题中,您可以简单地说:
lines = f.readlines() # read all lines of the file without '\n'
for l in lines:
l.strip(' ') # remove extra spaces at the start or end of line if you need