Объяснение того, что вам нужно:
Вам нужно искать точное совпадение слова в файле, а не только in
, потому что это всегда будет возвращать True
и, следовательно, он будет обходить:
Пример:
NamesList:
Fof
Abc
Def
и затем:
import re
text = input("enter Name to be searched:")
NamesFile = open("NamesList.txt", "r")
for line in NamesFile:
if re.search(r"\b" + text + r"\b", line):
print(line)
else:
print("Name not found")
break
OUTPUT ]:
enter Name to be searched:Fof
Fof
В другом случае :
enter Name to be searched:f
Name not found
Три вещи
Во-первых, ваши () ошибочны.
Во-вторых, результат subprocess.Popen ()
является объектом процесса, а не файл.
proc = []
proc.append(Popen(['svn', 'blame', shellquote(filename)], stdout=PIPE))
proc.append(Popen(['tr', '-s', r"'\040'"], stdin=proc[-1]), stdout=PIPE)
Значение proc [-1]
- это не файл, а процесс, содержащий файл.
proc.append(Popen(['tr', '-s', r"'\040'"], stdin=proc[-1].stdout, stdout=PIPE))
В-третьих, не делайте всего этого tr
и режут
мусор в оболочке, мало что может быть медленнее. Напишите обработку tr
и cut
в Python - это быстрее и проще.
В скрипте есть несколько странных вещей,
Почему вы храните каждый процесс в списке? Разве не было бы намного более удобочитаемым просто использовать переменные? Удаление всех .append () s
выявляет синтаксическую ошибку, несколько раз вы передавали stdout = PIPE аргументам append
вместо Popen:
proc.append (Popen (...), стандартный вывод = ТРУБА)
Таким образом, прямая перезапись (все еще с ошибками, о которых я упомяну через секунду) станет ..
def get_blame (filename):
виноват = попен (['svn', 'обвинить', цитата (имя файла)], стандартный вывод = ТРУБА)
tr1 = Popen (['tr', '-s', r "'\ 040'"], stdin = вина, стандартный вывод = ТРУБА)
tr2 = Popen (['tr', r "'\ 040'", r "';'"], stdin = tr1), stdout = PIPE)
cut = Popen (['cut', r "-d", r "\;", '-f', '3'], stdin = tr2, stdout = PIPE)
возврат cut.stdout.read ()
В каждой последующей команде вы передаете объект Popen, , а не , который обрабатывает stdout
. Из раздела «Замена конвейера оболочки» в документации по подпроцессам вы делаете ..
p1 = Popen (["dmesg"], stdout = PIPE)
p2 = Popen (["grep", "hda"], stdin = p1.stdout, stdout = PIPE)
..whereas you were doing the equivalent of stdin=p1
.
The tr1 =
(in the above rewritten code) line would become..
tr1 = Popen(['tr', '-s', r"'\040'"], stdin=blame.stdout, stdout=PIPE)
You do not need to escape commands/arguments with subprocess, as subprocess does not run the command in any shell (unless you specify shell=True
). See the Securitysection of the subprocess docs.
Instead of..
proc.append(Popen(['svn', 'blame', shellquote(filename)], stdout=PIPE))
..you can safely do..
Popen(['svn', 'blame', filename], stdout=PIPE)
As S.Lott suggested, don't use subprocess to do text-manipulations easier done in Python (the tr/cut commands). For one, tr/cut etc aren't hugely portable (different versions have different arguments), also they are quite hard to read (I've no idea what the tr's and cut are doing)
If I were to rewrite the command, I would probably do something like..
def get_blame(filename):
blame = Popen(['svn', 'blame', filename], stdout=PIPE)
output = blame.communicate()[0] # preferred to blame.stdout.read()
# process commands output:
ret = []
for line in output.split("\n"):
split_line = line.strip().split(" ")
if len(split_line) > 2:
rev = split_line[0]
author = split_line[1]
line = " ".join(split_line[2:])
ret.append ({'rev': rev, 'author': author, 'line': line})
возвратный ответ
Вы хотите стандартный вывод процесса, поэтому замените ваш stdin = proc [-1]
на stdin = proc [-1] .stdout
Кроме того, вам нужно переместить парена, он должен следовать после аргумента stdout
.
proc.append(Popen(['tr', '-s', r"'\040'"], stdin=proc[-1]), stdout=PIPE)
должно быть:
proc.append(Popen(['tr', '-s', r"'\040'"], stdin=proc[-1].stdout, stdout=PIPE))
Исправить другие ваши вызовы append
таким же образом.
выглядит как синтаксическая ошибка. за исключением первого добавления, остальные являются ошибочными (обзор скобок).
Как сказал С.Лотт, обработка текста в Python лучше.
Но если вы хотите использовать утилиты cmdline, вы можете сохранить его читабельным, используя shell = True
:
cmdline = r"svn blame %s | tr -s '\040' | tr '\040' ';' | cut -d \; -f 3" % shellquote(filename)
return Popen(cmdline, shell=True, stdout=PIPE).communicate()[0]