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

Bash 删除常规文本文件中的字母间距,bash,awk,sed,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

我有一个文本文件,它有很多行,行间距为字母,即

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

谢谢

如果您想要的是年预言的,那么使用awk并不困难:

单行程序① 在以下位置拆分一行:,② 删除以下内容后的所有空格:,③ 在每个大写字母前面加一个空格,并在第一个大写字母前面加一个空格④ 打印:、a:和之前的$1的串联
$2,即修改后的第二部分。

如果您想要的是年预言的东西,那么使用awk并不困难:

单行程序① 在以下位置拆分一行:,② 删除以下内容后的所有空格:,③ 在每个大写字母前面加一个空格,并在第一个大写字母前面加一个空格④ 打印:、a:和之前的$1的串联
$2,即修改后的第二部分。

我在评论中提到,您可以使用sed进行此操作。试过之后,我对sed失去了希望,因为我无法让lookarounds在他们的正则表达式中工作。显然,perl命令可以用lookarounds解析正则表达式。如果您有perl命令,可以尝试以下操作

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

这个篱笆柱到底是什么意思? perl选项-e告诉perl命令接受一个脚本,该脚本就是您在它后面看到的异常正则表达式,-p将围绕文件循环该脚本。我不是perl专家,所以我需要有人仔细检查一下,我只是看了一下perl-h来寻求帮助

现在是正则表达式

s///g遵循sed的语法。它将全局搜索并用替换

这里的匹配是[a-z]?=|$,它告诉perl将位置与后跟小写字母[a-z]的空格进行匹配,其中[a-z]表示要匹配的字符集,并表示该部分中使用的捕获组

为了确保后面是空格还是行尾?=|$,这就是我之前提到的[积极的]前瞻。竖条表示或。因此,lookahead将搜索空格或行$的结尾。前瞻确保了正确的匹配,同时不包括匹配中的空格/结束

替换为\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,那将包括一些、单词和这里。所以我们匹配小写字母,前后都有空格。我们通过匹配删除第一个空格,只替换字母,删除空格

此正则表达式的限制 如果你的档案有

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
不像冒号后面匹配那样精确,但正则表达式仍然是一个简短的hack“\_ツ_/''


进一步阅读:

我在评论中提到,您可以使用sed进行此操作。试过之后,我对sed失去了希望,因为我无法让lookarounds在他们的正则表达式中工作。显然,perl命令可以用lookarounds解析正则表达式。如果您有perl命令,可以尝试以下操作

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

这个篱笆柱到底是什么意思? perl选项-e告诉perl命令接受一个脚本,该脚本就是您在它后面看到的异常正则表达式,-p将围绕文件循环该脚本。我不是perl专家,所以我需要有人仔细检查一下,我只是看了一下perl-h来寻求帮助

现在是正则表达式

s///g遵循sed的语法。它将全局搜索并用替换

这里的匹配是[a-z]?=|$,它告诉perl将位置与后跟小写字母[a-z]的空格进行匹配,其中[a-z]表示要匹配的字符集,并表示该部分中使用的捕获组

为了确保后面是空格还是行尾?=|$,这就是我之前提到的[积极的]前瞻。竖条表示或。因此,lookahead将搜索空格或行$的结尾。前瞻确保了正确的匹配,同时不包括匹配中的空格/结束

替换为\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,那将包括一些、单词和这里。所以我们匹配小写字母,前后都有空格。我们通过匹配删除第一个空格,只替换字母,删除空格

此正则表达式的限制 如果你的档案有

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
不象船尾那样精确 呃,冒号,但正则表达式仍然是一个短的hack'\_ツ_/''


进一步阅读:

这可能适用于GNU-sed:

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

将当前行中后跟小写字符的空格的所有大小写替换为后跟:的小写字符。此解决方案沿着这条路线一直运行,直到满足所有情况后失败。

这可能适用于GNU-sed:

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

将当前行中后跟小写字符的空格的所有大小写替换为后跟:的小写字符。这个解决方案沿着这条路线一直运行,直到它在满足所有情况后失败。

这里是使用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

这里还有一个使用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

GESUB的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

GESUB的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

这个问题可以用许多不同的方法来解决。我能想到的最简单的方法就是在小写之前去掉空格。我已经尝试过使用SED,正如前面提到的,SED的正则表达式中没有lookaround

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'
输出:敏捷的棕色狐狸跳过懒惰的狗
这个问题可以用许多不同的方法来解决。我能想到的最简单的方法就是在小写之前去掉空格。我已经尝试过使用SED,正如前面提到的,SED的正则表达式中没有lookaround

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'
输出:敏捷的棕色狐狸跳过懒惰的狗

你试过什么?什么是单词定界符?你也可能是输入错误,但为什么在某个单词后面有空格:但在result.txt中的某个打油诗后面没有空格?sed或awk怎么可能能够区分跳跃中的J和u之间的空格,即从要保留的x和J之间的空格中删除的空格?TL;用你提到的工具,你的任务是不可能完成的。@GBOFI我猜应该保留大写字母前的空格。但OP应该更加明确。此外,我认为sed也是可能的,但这取决于OP的实际需求@投石机啊,我站好了。如果这是他们想要的,这是可以做到的…你试过什么?什么是单词定界符?你也可能是输入错误,但为什么在某个单词后面有空格:但在result.txt中的某个打油诗后面没有空格?sed或awk怎么可能能够区分跳跃中的J和u之间的空格,即从要保留的x和J之间的空格中删除的空格?TL;用你提到的工具,你的任务是不可能完成的。@GBOFI我猜应该保留大写字母前的空格。但OP应该更加明确。此外,我认为sed也是可能的,但这取决于OP的实际需求@投石机啊,我站好了。如果这是他们想要的,可以这样做…在某些地区,A-Z包括大多数小写字母,因为它们是按aAbBcC…zZ或类似方式订购的,而不是abc…zABC…Z。使用字符类[[:upper:]而不是[A-Z]来避免该问题。在某些地区,A-Z包含大多数小写字母,因为它们的顺序是aAbBcC…zZ或类似字母,而不是abc…zABC…Z。使用字符类[[:upper:]而不是[A-Z]来避免该问题。您错过了一件使sed很难执行的事情,即替换只能发生在第一个之后的替换字符串中:。使用实际的示例输入尝试您的建议,看看它是如何失败的。您错过了一件使sed很难执行的事情,那就是替换只能在第一个之后的替换字符串中发生:。用实际的示例输入尝试您的建议,看看它是如何失败的。