我有一个文本文件。这是一个大文本文件,该文件包含一些如下所示的模式:
(1), (3), (1,2,3), (1,2,3,4,5,6,7,8,9)
...就像这样,
(Fig1) (Fig1,Fig2), (Table-1, Table-2) etc.
我想要这样的输出
[1], [3], [1,2,3], [1,2,3,4,5,6,7,8,9], (Fig1) (Fig1,Fig2), (Table-1, Table-2)
我的意思是我只想将 () 更改为仅包含数字的 []。请帮我
答案1
和sed
:
sed 's/(\([0-9,]*\))/[\1]/g' filename.txt
[0-9,]*
是匹配任意数量的数字和逗号的正则表达式。我将它包含在其中,\(\)
以便我可以在替换字符串中将其重用为\1
.不带反斜杠的简单括号代表其自身。它们被替换为[]
(在替换字符串中没有特殊含义)。
答案2
Python 3 脚本解决方案
下面的脚本是一个更明确的“手动”解决方案,它不使用正则表达式,但在完成这项工作时需要考虑一些额外的注意事项。其操作的关键是脚本打开以读取我们在命令行上提供的任何文件,迭代每行中的每个字符,寻找括号。如果我们看到括号,我们就记录里面的内容,然后扔掉逗号后,我们决定这是否是数字字符串。如果它是数字字符串 - 记录的项目将进入单词列表,稍后使用带有分隔符的.join()
函数将其重建为一行", "
。非常坦率的。
#!/usr/bin/env python3
import sys
with open(sys.argv[1]) as fd:
for line in fd:
# we're going to store everything into list of words
# and record individual characters into 'item' string
# and rebuild everything as we go.
words = []
item_found = False
item = ""
counter = 0
for char in line:
# if we see ( or [ we start recording chars
# difference is that [ means item already been edited
# so no need to do anything - just put it into words list
# as is
if char == "(" or char == "[":
item_found = True
counter = counter + 1
continue
if char == ")":
item_found = False
if item.replace(",","").isdigit():
words.append("[" + item + "]")
else:
words.append("("+item+")")
item = ""
if char == "]":
item_found = False
item = item + char
words.append("[" + item)
item = ""
if item_found:
item = item + char
# if we didn't see any open brackets or no closing brackets
# just print the line as is - otherwise give us the altered one
if counter == 0 or item_found:
print(line.strip())
else:
print(", ".join(words))
测试运行:
我随意使用 OP 的输入来包含额外的 2 行,其中包含几个不同的测试用例。
$ # original input file
$ cat input.txt
(1), (3), (1,2,3), (1,2,3,4,5,6,7,8,9), (Fig1) (Fig1,Fig2), (Table-1, Table-2)
(table-25),[1,2,3],(figure-35)
(figure-1),(figure-2)
$ # script output
$ ./change_brackets.py input.txt
[1], [3], [1,2,3], [1,2,3,4,5,6,7,8,9], (Fig1), (Fig1,Fig2), (Table-1, Table-2)
(table-25), [1,2,3], (figure-35)
(figure-1), (figure-2)
对于 40,000 行文本,它执行得相当快:
$ wc -l big_input.txt
40000 big_input.txt
$ time ./change_brackets.py big_input.txt > /dev/null
0m01.64s real 0m01.60s user 0m00.01s system
可能的改进建议(以及解决斯蒂芬提到的事情之一) 是将if item.replace(",","").isdigit()
线改为if item.replace(",","").replace(".","").isdigit()
.这也将使我们能够处理浮点数(例如 3.1415)。
冗长?是的。明确?是的。有效吗?嗯,是。
答案3
sed -E 's/[(](([0-9]+,?)+)[)]/[\1]/g'
sed -e 's/(\(\([0-9]\{1,\},\{0,\}\)\{1,\}\))/[\1]/g'
我们正在寻找正则表达式 [0-9]+,?至少出现一次并且同时出现,由 ( 和 ) 括号包围。成功时外括号更改为 [ ]。
第二个 sed 语句是上述语句的 POSIXly 版本。