我有一个文件/etc/sysctl.conf,想要搜索以下2个字符串。如果找不到这样的字符串,我们需要在文件后追加相同的字符串。如果找不到完全匹配的内容,我们需要对其进行更正或删除行并添加。如果完全匹配未对文件执行任何操作。 我无法替换文件。请指导。
搜索字符串:
net.ipv4.ipfrag_low_thresh = 15728640 net.ipv4.ipfrag_high_thresh = 16777216
我的代码
#/usr/bin/python
import os,datetime,shutil,re
num1 = 'net.ipv4.ipfrag_low_thresh = 15728640'
num = "net.ipv4.ipfrag_high_thresh = 16777216"
''' This Programme checks ipfrag value in /etc/sysctl.conf .
It also checks parameter in /proc/net/ip4
'''
date = datetime.datetime.today().strftime('%Y-%m-%d')
find_low_thresh=re.compile(r'net.ipv4.ipfrag_low_thresh\s*=\s*15728640')
find_high_thresh=re.compile(r'net.ipv4.ipfrag_high_thresh\s*=\s*16777216')
find_low_thresh1 = re.compile(r'net.ipv4.ipfrag_low_thresh*')
find_high_thresh1 = re.compile(r'net.ipv4.ipfrag_high_thresh*')
low_count=0
for i, line in enumerate(open("/etc/sysctl.conf", "r")):
for match in re.finditer(find_low_thresh1,line):
print(match.group())
S3=match.group()
print(S3)
low_count+=1
if low_count == 0:
print("Count is Zero and no match found")
with open("/etc/sysctl.conf", "a") as myfile:
myfile.write( "net.ipv4.ipfrag_low_thresh = 15728640\n")
elif low_count == 1:
print("Counter is one")
with open("/etc/sysctl.conf", "a") as myfile:
myfile.write(re.sub("net.ipv4.ipfrag_low_thresh","net.ipv4.ipfrag_low_thresh = 15728640\n"))
else:
print("Do Nothing")
#####################################################
if os.path.isfile("/etc/sysctl.conf." + date):
print("File already exists")
else:
print("It Does not exists,Copying file")
shutil.copy("/etc/sysctl.conf", "/etc/sysctl.conf."+date)
if os.path.isfile("/etc/sysctl.conf." + date):
S2="File already exists"
print(S2)
else:
print("File copiped")
答案 0 :(得分:1)
这是使用python数据类型而不是仅使用字符串正则表达式的另一种方法(弄乱正则表达式并破坏文件结构太容易了。)
使用伪造的示例文件:
# hash comment
; colon comment
one = 1
net.ipv4.ipfrag_low_thresh = 1234
another = ok
代码:
#!/usr/bin/env python
setting_map = {
'net.ipv4.ipfrag_low_thresh': 15728640,
'net.ipv4.ipfrag_high_thresh': 16777216,
}
found = {setting: False for setting in setting_map}
to_write = []
def good_setting(setting):
return '{} = {}'.format(setting, setting_map[setting])
with open('sysctl.conf') as f:
for line in f:
line = line.rstrip() # remove newlines
try:
setting = line.split('=')[0].strip() # remove spaces if present
value = int(line.split('=')[-1].strip())
except Exception as e:
# you probably don't want to print, but i put it here for demonstration
print('could not parse line "{}"; exception: {}'.format(line, repr(e)))
# keep it as-is
to_write.append(line)
continue
if setting in setting_map:
found[setting] = True
if value != setting_map[setting]:
print('FOUND "{}" with value "{}"; overwriting with "{}"'.format(
setting, value, setting_map[setting]
))
to_write.append(good_setting(setting))
continue
to_write.append(line)
# opening as 'w' will wipe the file, but we're re-writing every line
# or you can write to a different file if you'd like
with open('sysctl.conf', 'w') as f:
f.write('\n'.join(to_write))
f.write('\n')
for setting in setting_map:
if not found[setting]:
print('ADDING "{}"'.format(good_setting(setting)))
f.write('{}\n'.format(good_setting(setting)))
输出:
could not parse line "# hash comment"; exception: ValueError("invalid literal for int() with base 10: '# hash comment'")
could not parse line " ; colon comment"; exception: ValueError("invalid literal for int() with base 10: '; colon comment'")
could not parse line ""; exception: ValueError("invalid literal for int() with base 10: ''")
FOUND "net.ipv4.ipfrag_low_thresh" with value "1234"; overwriting with "15728640"
could not parse line "another = ok"; exception: ValueError("invalid literal for int() with base 10: 'ok'")
ADDING "net.ipv4.ipfrag_high_thresh = 16777216"
之后的文件:
# hash comment
; colon comment
one = 1
net.ipv4.ipfrag_low_thresh = 15728640
another = ok
net.ipv4.ipfrag_high_thresh = 16777216
答案 1 :(得分:0)
re.sub()
具有3个参数,但这不是真正的问题。您实际上不会用简单的文件写入来替换要尝试替换的文本,而无需先使用seek()
函数来查找要写入的偏移量。但是,这对您来说是个问题,因为替换字符串比原始字符串长,并且您最终可能会覆盖不想要的数据。另一个问题是您选择打开文件进行追加,在某些系统中,该文件只会追加到文件末尾,我确定这不是您的意图。
您真正需要做的就是打开文件并将数据复制到变量中。 然后,尝试找到该字符串并替换它。最后,将整个内容写回到文件中。
def write_over():
file_name = '/etc/sysctl.conf'
new_string = 'net.ipv4.ipfrag_low_thresh = 15728640'
fh = open(file_name, 'r+')
data = fh.read()
result = re.search(r'net\.ipv4\.ipfrag_low_thresh\s?=?\s?[0-9]*', data) # check this regex, it may not be exactly what you need
if result:
if result.group(0) == new_string: # if the string is exact match, do nothing
fh.close()
return
data = data.replace(result.group(0), new_string + '\n') # else replace with new string
fh.truncate(0) # this will clear the contents of the file
fh.seek(0)
fh.write(data) # write the new data in its entirety to the file
fh.close()
else:
fh.write('\n' + new_string) # if the line was not in the file at all
fh.close()