删除常规文本文件中的字母间距

时间:2018-12-15 10:52:39

标签: bash awk sed

我有一个文本文件,其中有很多行,并带有字母间距,即

cat test.txt
Some word here: T h e Q u i c k B r o w n F o x J u m p s O v e r T h e L a z y D o g
Some doggerel: J a c k A n d J i l l W e n t U p T h e H i l l

我要求使用Linux中的某些命令行工具,将一些正则表达式应用于此文本文件以删除字符之间的间距。

cat result.txt
Some word here: The Quick Brown Fox Jumps Over The Lazy Dog
Some doggerel: Jack And Jill Went Up The Hill

谢谢

6 个答案:

答案 0 :(得分:3)

如果您想要的是TrebuchetMSthis comment所定义的内容,那么使用awk并不困难:

$ awk -F: '{gsub(/ /,"",$2); gsub(/[A-Z]/," &",$2) ; print $1":"$2}' file.txt

单行程序①在:上分割一行,②删除:之后的所有空格,③在每个大写字母前都添加一个空格(也在第一个大写字母之前) )和④打印$1(在:之前的字符串),:$2,即修改后的第二部分。

答案 1 :(得分:2)

我在评论中提到您可以使用sed。经过尝试之后,由于无法获得环顾他们的正则表达式的经验,我对sed失去了希望。显然,perl命令可以解析具有正则表达式的正则表达式。如果您有perl命令,可以尝试一下

perl -pe 's/ ([a-z])(?= |$)/\1/g' file.txt

cat file.txt | perl -pe 's/ ([a-z])(?= |$)/\1/g'

这个栅栏柱到底是什么意思?

perl选项-e告诉perl命令接受脚本(这是您在其后立即看到的奇异正则表达式),而-p将使脚本在文件。 (我不是perl专家,所以我需要有人仔细检查一下,我只是看着perl -h寻求帮助。)

现在是正则表达式。

s/<match>/<replace>/g遵循sed的语法。它会sg处大地<match>,并用<replace>代替。

在这里,匹配项为([a-z])(?= |$),它告诉perl匹配带有空格的地方,后跟一个小写字母(([a-z]),其中[a-z]表示匹配的字符,()代表捕获组,在<replace>部分中使用。)

然后,以确保紧随其后的是空格还是行尾((?= |$)),这就是我之前所指的[正面]前瞻。竖线表示“或”。因此,先行搜索将搜索空格()“或”行尾($)。前瞻确保正确的匹配,同时在匹配中不包含空格/结尾。

替换为\1,它将替换为第一个捕获组。在这种情况下,捕获组就是匹配的小写字母。

为什么此正则表达式有效

如果您查看文本文件的第一行:

Some word here: T h e Q u i c k B r o w n F o x J u m p s O v e r T h e L a z y D o g

我们只想匹配小写字母,后跟一个空格,即a-z。如果我们匹配a-z,则它将包括Somewordhere。因此,我们将小写字母匹配在一起,在前面和后面都有空格。我们通过匹配第一个空格来删除它,方法是只替换字母,然后删除空格。

此正则表达式的限制

如果您的文件包含

Lol a word here: T h e Q u i c k B r o w n F o x J u m p s O v e r T h e L a z y D o g

然后输出将包括:

Lola word here: The Quick Brown Fox Jumps Over The Lazy Dog

不如gboffi's answer准确,因为它与冒号 匹配。但是正则表达式仍然是简短的\ _(ツ)_ /¯。

进一步阅读:Reference: What does this regex mean?

答案 2 :(得分:2)

这可能对您有用(GNU sed):

 sed -r ':a;s/^(.*: .*) ([[:lower:]])/\1\2/;ta' file

在当前行的:之后,将所有空格的小写字母后跟小写字母替换为小写字母。该解决方案一直沿用至今,直到满足所有情况后才失效。

答案 3 :(得分:2)

使用gensub()的GNU awk:

$ awk 'BEGIN{FS=OFS=":"} {$2=gensub(/ ([^[:upper:]])/,"\\1","g",$2)}1' file
Some word here: The Quick Brown Fox Jumps Over The Lazy Dog
Some doggerel: Jack And Jill Went Up The Hill

任何awk:

$ awk 'BEGIN{FS=OFS=":"} {gsub(/ /,"",$2); gsub(/[[:upper:]]/," &",$2)}1' file
Some word here: The Quick Brown Fox Jumps Over The Lazy Dog
Some doggerel: Jack And Jill Went Up The Hill

答案 4 :(得分:1)

这里是使用Perl的另一种变体

$ cat peter.txt
Some word here: T h e Q u i c k B r o w n F o x J u m p s O v e r T h e L a z y D o g
Some doggerel: J a c k A n d J i l l W e n t U p T h e H i l l

$ perl -F":" -lane ' $F[1]=~s/ //g; $F[1]=~s/([A-Z])/ \1/g; print "$F[0]:$F[1]" ' peter.txt
Some word here: The Quick Brown Fox Jumps Over The Lazy Dog
Some doggerel: Jack And Jill Went Up The Hill

答案 5 :(得分:1)

可以通过许多不同方式解决此问题。我能想到的最简单的方法是在小写字母之前删除空格。我曾尝试使用SED,因为TrebuchetMS提到“ SED的正则表达式中没有环视功能”

echo "T h e Q u i c k B r o w n F o x J u m p s O v e r T h e L a z y D o g" |  sed 's/[[:blank:]]\([[:lower:]]\)/\1/g'

输出:敏捷的棕色狐狸跳过了懒狗 enter image description here