我有一个包含内容的大文本文件,如下例所示:
number="+123 123 123" text="This is some text"
number="+123456" text="This may contain numbers"
number="+123456 789" text="Numbers here should keep their spaces"
number="+9 8 7 6 5" text="example 123 123 123"
我想要的是删除两个识别字符串之间的任何空白字符,在这种情况下number=
和" text=
而不触及其余部分。这样所需的输出就是:
number="+123123123" text="This is some text"
number="+123456" text="This may contain numbers"
number="+123456789" text="Numbers here should keep their spaces"
number="+98765" text="example 123 123 123"
像(?<=[0-9])(\s)(?=[0-9])
这样的正则表达式会干扰文本字段,这是不可取的。
我已经测试了使用(?<=address)(\s)(?=date)
行的一些变体,但这不起作用。我认为问题在于无法处理空格和标记之间的额外可能数字?
将通配符匹配添加到lookbehinds / lookaheads(例如(?<=address.*)(\s)(?=.*date)
)似乎无效,否则我做错了?使用(/s+?)
使空白变得懒惰似乎对我没有帮助,但这是关于我对正则表达式的知识真正崩溃的地方:)
理想情况下,我还想在额外的等于和引号字符之间限制安全性。 I.e number="
位于开头标记处,text="
作为结束标记。
如果更容易,也欢迎任何sed / awk或类似的解决方案。
答案 0 :(得分:4)
使用awk
:
awk 'BEGIN{FS=OFS="\""}{gsub(/ /,"",$2)}1' file
number="+123123123" text="This is some text"
number="+123456" text="This may contain numbers"
number="+123456789" text="Numbers here should keep their spaces"
number="+98765" text="example 123 123 123"
答案 1 :(得分:3)
使用替换和循环:
sed ':l s/\(number="[^" \t]*\)\s\s*/\1/g;tl' input
这个给出:
number="+123123123" text="This is some text"
number="+123456" text="This may contain numbers"
number="+123456789" text="Numbers here should keep their spaces"
number="+98765" text="example 123 123 123"
答案 2 :(得分:2)
搜索: [ ](?=[^"]*" text=)
(空间周围的[brackets]
是可选的,为了清晰起见,它们在那里)
替换:空字符串。
在the regex demo中,请参阅底部的替换。
命令行语法
我不知道要搜索和替换的sed语法。使用Perl(由@jaypal和@AvinashRaj提供):
perl -pe 's/ (?=[^"]*" text=)//g' file
来自perl --help
,
-p assume loop like -n but print line also, like sed
-e program one line of program (several -e's allowed, omit programfile)
答案 3 :(得分:1)
另一个awk
解决方案:
awk -F ' text="' '{ gsub(/ /, "", $1); print $1 FS $2 }' file
-F text="'
将每个输入行拆分为text="
($1
)之前的部分,而$2
之后的部分 - -F
选项将特殊FS
(* f * ield * s * eparator)awk
变量到awk
用于将每个输入行拆分为字段的正则表达式。gsub(/ /, "", $1)
(* g * lobal * sub * stitution)删除$1
中的所有空格(text="
之前的部分;用空字符串替换空格。)print $1 FS $2
打印输出:已修改 $1
(已移除空格),与FS
(即text="
)一起加入, $2
(text="
之后的未经修改的部分)。答案 4 :(得分:1)
注意:这是对现有答案的补充,比较其效果。
测试环境:
缺少:
awk
解决方案最快。
perl
solution。sed
solution (accepted answer) 最慢。
g
选项 可以显着改善事物,但不会改变大局。在OS X上,差异并不显着
在Ubuntu上,awk
和perl
解决方案之间的差异很小,但sed
解决方案的速度要慢得多。
样本编号,针对100,000行输入文件运行10次。
不要直接比较它们(Ubuntu在OS X机器上的VM中运行),只需看看它们的比率。 (奇怪的是,awk
和perl
在Ubuntu VM中运行更快:
OS X:
# awk (@japyal) real 0m3.848s user 0m3.773s sys 0m0.049s # awk (@mklement0) real 0m4.011s user 0m3.959s sys 0m0.045s # perl real 0m4.382s user 0m4.291s sys 0m0.063s # sed real 0m4.867s user 0m4.816s sys 0m0.044s # sed (no `g`) real 0m4.510s user 0m4.460s sys 0m0.044s
Ubuntu的:
# awk (@mklement0) real 0m1.850s user 0m1.788s sys 0m0.020s # awk (@jaypal) real 0m2.055s user 0m1.996s sys 0m0.012s # perl real 0m2.349s user 0m2.276s sys 0m0.024s # sed real 0m8.278s user 0m8.196s sys 0m0.016s # sed (no `g`) real 0m7.580s user 0m7.488s sys 0m0.028s