2016-04-22 36 views
0

我已经看到了很多解决方案,但是我没有看到其中的一个解决方案我试图在特定字符串的Python目录中查找每个文件,计算grep返回的行数,并用python记录下来。这是我曾尝试最近:使用Python获取目录中图像名称的grep结果的行数

for f in try_files: 
    print("trying %s"%f) 
    s = subprocess.Popen("grep -r '%s' ../dir/*"%f) 
    print(s) 

我收到此错误:

trying accept_button_off_transparent.png 
Traceback (most recent call last): 
    File "findImages.py", line 17, in <module> 
    s = subprocess.Popen("grep -r %s '../dir/*'"%f) 
    File "/Users/agsrn/anaconda3/lib/python3.5/subprocess.py", line 950, in __init__ 
    restore_signals, start_new_session) 
    File "/Users/agsrn/anaconda3/lib/python3.5/subprocess.py", line 1544, in _execute_child 
    raise child_exception_type(errno_num, err_msg) 
FileNotFoundError: [Errno 2] No such file or directory: "grep -r accept_button_off_transparent.png '../dir/*'" 
Agsrn-MacBook-Pro:images agsrn$ emacs findImages.py 
Agsrn-MacBook-Pro:images agsrn$ python findImages.py 
['accept_button_off_transparent.png', 'accept_button_on.png', 'accept_button_on_food.png', 'accept_button_on_transparent.png'] 
trying accept_button_off_transparent.png 
Traceback (most recent call last): 
    File "findImages.py", line 17, in <module> 
    s = subprocess.Popen("grep -r '%s' ../dir/*"%f) 
    File "/Users/agsrn/anaconda3/lib/python3.5/subprocess.py", line 950, in __init__ 
    restore_signals, start_new_session) 
    File "/Users/agsrn/anaconda3/lib/python3.5/subprocess.py", line 1544, in _execute_child 
    raise child_exception_type(errno_num, err_msg) 

最后,我想从Python中执行这个查询:

grep -r "filename" ../dir/* | wc -l 

...而将该行数作为一个#我可以用于其他逻辑。什么是最好的方法来做到这一点?

为了清楚起见,我的最终目标是统计目录中的任何/所有文件提及某个字符串列表的次数。我正在寻找文件内的字符串,而不仅仅是文件名。我怀疑grep是一个比Python更快的解决方案,但它在更大的Python例程中,因此是所提出的混合解决方案。

+0

你是开放的具有计数,工程文件的解决方案?或者你只想用grep来做到这一点? – Alejandro

回答

0

,可能是因为此,从docs: “如果参数表是一个字符串,则解释是依赖于平台的[...]在POSIX,如果参数表是一个字符串,字符串被解释为名称或要执行的程序的路径。“

您看到的错误说明您的字符串被解释为文件名,所以它符合此描述。尝试改为将参数作为列表传递:

subprocess.Popen(["grep", "-r", f, "../dir/*"], shell=True) 
+0

感谢您的建议。不幸的是,这个解决方案让我回到了另一个问题。当我运行这个,没有错误,但我得到以下内容:grep:../dir/*:即使有这样的文件/目录,也没有这样的文件或目录。 – helloB

+0

您是否尝试过打印'glob.glob('../ dir')'?所以我们确信。在你的问题的一个版本中,你搜索“../dir*”,而另一个版本是“../dir/*”(带斜线)。 – JulienD

+0

@helloB好吧,你需要:http://stackoverflow.com/questions/9997048/python-subprocess-wildcard-usage。我用它编辑我的答案。请注意以下警告:https://docs.python.org/3/library/subprocess.html#security-considerations – JulienD

0

如果您接受另一个解决方案,则在此。计数文件可以使用glob方便地执行:

import glob 
files = glob.glob("filename") 
nfiles = len(files) 

其中“文件名”具有您​​想要的模式。然后,你可以用你的逻辑来使用nfiles。

+0

我不是要计数文件。我正在尝试为某个特定字符串查找目录中的所有文件,而且我正计划对很多字符串执行此操作,以识别不在字符串列表中的目录内的任何文件内使用的字符串。 – helloB

0

或者我的其他答案,你可能想尝试在Python做完全是这样的:

import re # regex module 

for filename in files: 
    n = 0 
    for line in open(filename, 'r'): 
     if re.match(r"...", line): 
      n += 1 
+0

是的,但正如我所说这可能会比grep慢很多。 – helloB

+0

当然。有些人还喜欢Perl的那种东西。 – JulienD

0

以下shell命令将输出所需的计数:

find ../dir -type f -exec cat {} + | grep -c 'filename' 

find命令将打印目录中所有文件的内容,并且-c选项为grep指示它打印匹配计数而不是匹配行。

您可以使用subprocess.Popen()运行此命令。您需要使用shell=True选项,以便将其作为shell命令处理,而不是要运行的程序的名称。要获得命令的输出,您需要指定stdout=PIPE并使用communicate来读取它。

pipe = subprocess.Popen("find ../dir -type f -exec cat {} + | grep -c '%s'"%f, shell=True, stdout=PIPE) 
count = int(pipe.communicate()[0]); 

Store output of subprocess.Popen call in a string