Удаление нецелых чисел из полученной строки grep с Python и Bash - PullRequest
0 голосов
/ 11 сентября 2018

Я использую grep, чтобы извлечь текст из файла:

NELECT = 44.0000   total number of electrons,

, и мне нужно сохранить число в качестве переменной.Я попробовал несколько методов, которые я нашел здесь, таких как использование фильтров и findall.По какой-то причине я могу заставить его отделить только один ноль.

Пока код выглядит так:

wd=os.getcwd()
electrons=str(os.system("grep 'NELECT' "+wd+"/OUTCAR"))
VBM=(re.findall('\d+', electrons))
print VBM

И взамен я получаю ['0'].

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Результатом os.system является состояние выхода команды, а не ее вывод - см. https://docs.python.org/3/library/os.html#os.system

$ cat OUTCAR 
NELECT = 44.0000   total number of electrons,

$ python
Python 2.7.12 (default, Dec  4 2017, 14:50:18) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> result = os.system("grep 'NELECT' "+os.getcwd()+"/OUTCAR")
NELECT = 44.0000   total number of electrons,
>>> result
0

Строка «NELECT» была просто выведена grep в stdout, но не записывается в переменную результата

>>> from subprocess import check_output
>>> result2 = check_output(["grep", "NELECT", os.getcwd()+"/OUTCAR"])
>>> result2
'NELECT = 44.0000   total number of electrons,\n'
>>> import re
>>> re.findall(r'\d+', result2)
['44', '0000']

Или не вызывайте grep, прочитайте файл самостоятельно

>>> import os
>>> import re
>>> with open(os.getcwd() + "/OUTCAR") as f:
...   for line in f:
...     if "NELECT" in line:
...       digits = re.findall(r'\d+', line)
...       break
...
>>> digits
['44', '0000']

Или, возможно, не используйте регулярное выражение:

>>> words = line.split()
>>> words[2]
'44.0000'
>>> int(float(words[2]))
44
0 голосов
/ 12 сентября 2018

Вы уверены, что electrons имеет указанный вывод? Для меня это регулярное выражение возвращает список с двумя элементами: ['44', '000'] и это ожидаемое поведение. Так что, скорее всего, что-то не так с grep call.

Ваше регулярное выражение не будет извлекать целые 44.000, так как \d+ ловит только непрерывные строки цифр, без точечных символов. Чтобы получить целое число, используйте что-то вроде \b\d+\.\d+\b, что означает: любое слово (\b означает начало / окончание слова, точка должна быть экранирована как . в регулярном выражении, совпадающем с любым символом), которое содержит по крайней мере 1 цифру, точку и по крайней мере Еще 1 цифра Если точка необязательна, то что-то вроде этого: \b(\d+(?:\.\d+)?)\b ((?:) создает группу, которая не будет захвачена, поэтому ваш вывод будет по-прежнему одним списком элементов).

Обратите внимание, что re.findall вернет список совпадений строк. Чтобы получить номер из первого матча: float(VBM[0])

Редактировать. Забыл добавить: избегайте использования оператора print, он работает странным образом с кортежами и полностью удален в Python 3. Поддержка Python 2 заканчивается в 2020 году, поэтому лучше подготовиться. Вы можете заменить оператор печати на функцию печати Python 3, добавив from __future__ import print_function в начале файла.

...