简体   繁体   English

当从python调用时,Grep不断返回0

[英]Grep continually returning 0 when called from python

Background: I have a lot of music. 背景:我有很多音乐。 I also tend to listen to the same albums over and over. 我也倾向于一遍又一遍地听同一张专辑。 Eventually, this annoyed me to the point where I decided I'd listen to a different one each day. 最终,这让我很生气,我决定每天都听一个不同的。 Seeing as I have just over 100 albums in my collection, and seeing as I know a little programming, I thought I'd write a script to help myself out. 看到我的收藏中只有100多张专辑,看到我知道一点点编程,我想我会编写一个脚本来帮助自己。

Now, keep in mind, I'm a student who knows he knows very little. 现在,请记住,我是一个知道自己知之甚少的学生。 Most of what I know has been from a single Python book (though a decent one for getting beginners off the ground) and the Python documentation. 我所知道的大部分内容都来自一本Python书(虽然它是一个让初学者能够开始的好书)和Python文档。

Also, I'm running Python 3.6 and using Cygwin, so I do have *nix commands available. 另外,我正在运行Python 3.6并使用Cygwin,所以我确实有* nix命令可用。

The problem lies in the following method (edit 9:43 EST - suggested "if line in file" implementation added; new lines starred): 问题在于以下方法(编辑9:43 EST - 建议“如果文件中有行”实现添加;新行加星标):

def choose_album(library_file, day_file):
    albums = []
    for line in fileinput.input(library_file):
        albums.append(line)
    fileinput.close() #**
    check_file = io.open(day_file) #**
    album_chosen = False #**
    while album_chosen == False:
        choice = random.randrange(0, len(albums))
        print("Searching for " + albums[choice] + ".")
        for line in check_file: #**
            if albums[choice] in line: #**
                break #**
        if albums[choice] not in check_file: #**
            album_chosen = True #**
    print(albums[choice])
    return albums[choice]

where the library_file is a text file with all of the albums I have purchased or listened to on Spotify and the day_file is my "album of the day" file, each line containing a date and the album for that day. 其中library_file是一个文本文件,包含我在Spotify上购买或收听的所有专辑,day_file是我的“当天专辑”文件,每行包含当天的日期和专辑。 The while loop used to be an while循环曾经是一个

if albums[choice] in line:
    break

and then the script would go on to write that to the day_file. 然后脚本会继续将其写入day_file。 It worked fine, but the problem was that the if albums[choice] in line line would sometimes return false negatives, giving me an album I'd already listened to, meaning I'd have to go back into my file, delete the redundant album, and run the script again. 它工作正常,但问题是,行中的if albums[choice] in line有时会返回假阴性,给我一张我已经听过的专辑,这意味着我必须回到我的文件中,删除多余的专辑,然后再次运行脚本。

Update (9:43 EST) Based on my test run of the edited code, this at least doesn't spit out heaps of text. 更新(美国东部时间9点43分)基于我对已编辑代码的测试运行,这至少不会吐出大量文本。 Is it likely to give me duplicates again? 它可能会再次给我重复吗?

Update (12:02 EST) - removed output that became irrelevant due to suggestion. 更新(美国东部时间12点02分) - 删除因建议而无关的输出。

You are reading lines without trimming the final newline: 您正在阅读线条而不修剪最终换行符:

for line in fileinput.input(library_file):
    albums.append(line)  ##### BUG

What you probably meant to write might be along the lines of 你大概意思写的可能是沿着线

    albums.append(line.rstrip('\n'))

The newline caused grep to print out every line. 换行符导致grep打印出每一行。 Somewhat to my surprise, after 25+ years as an active Unix user, I discovered that at least some versions of grep will cause 令我惊讶的是,在作为活跃的Unix用户25年以后,我发现至少某些版本的grep会导致

 grep 'String which ends with newline
 ' filename

to print out every line in filename , apparently because it considers this equivalent to 打印出filename每一行,显然是因为它认为这相当于

grep -e 'String which ends with newline' -e '' filename`

where obviously the empty string as a regular expression matches every possible input. 显然,作为正则表达式的空字符串匹配每个可能的输入。

Switching from grep to if albums[choice] in line removes this symptom, and actually happens to work because you are also not trimming newlines from lines you read from the other file, and you specifically look for matches which are at the end of the line; grep切换到if albums[choice] in line删除此症状,并且实际上恰好工作,因为您也没有从您从其他文件中读取的行修剪换行符,并且您专门查找位于行尾的匹配项; and so "foo\\n" in "datestamp foo\\n" actually returns True . 所以"foo\\n" in "datestamp foo\\n"实际上返回True However, this appears to be contrary to your expectations (for example, you are printing the string followed by a full stop, which lands after the embedded newline, on a line by itself in the output) so perhaps this is still a (minor) bug in your code. 但是,这似乎与您的预期相反(例如,您正在打印字符串后跟一个完整的停止,它在嵌入的换行符之后落在输出中的一行上)所以这可能仍然是(次要的)代码中的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM