我想清理一些文件,并使它们的编写方式更加统一。
所以,我的输入看起来像这样:
$a$h$l)r ^9 ^5 升 \ 乌尔德
问题是,有些空格是“不必要的”,使得比较文件变得困难。因此,我想删除所有空格,除非它们直接跟在以下字符之一之后:
- $
- ^
- 时间
- iN(N为变量,任意字符1字节长)
- oN(N 是变量,如上所述)
- s
- sN(N 是变量,如上所述)
- @
- !
- /
- (
- )
- =N(N 是变量,如上所述)
- %N(N 是变量,如上所述)
因此,示例输入可能是:
: $$$N $$$a 单反相机 *56 长 氧1氧2 %%xv
想要的输出是:
: $$$N $$$a 萨斯利尔 *56升 氧1氧2 %%xv
对于这种%%x v
情况,空格被删除,因为它是首字母后面的第三个字符%
,其中第二个字符%
充当变量。
我正在使用 GNU/Linux 操作系统。
答案1
我想我现在明白了——谢谢。
使用扩展的正则表达式来处理额外字符的选项氮容易一点(请注意,此处使用的示例输入与问题中您自己的输入略有不同):
sed -Ee's|([sio=%]..)?([@!T()^$/].)? *|\1\2|g' \
<<""
:
$ $ $N
$ $ $a
sa s l r
*56 l r
o1 o 2
%%xv
:
$ $ $N
$ $ $a
sa s lr
*56lr
o1 o 2
%%xv
您需要 GNU/BSD/ASTsed
才能使用它。等效的 BRE 如下所示:
sed 's|\([soi=%]..\)\{0,1\}\([@!T()^$/].\)\{0,1\} *|\1\2|g'
诀窍是使所有匹配最终都是可选的 - 这样模式的任何部分都不会优先。因为您实际上只是删除数据,而不是插入数据(这必须以不同的方式处理)在匹配目标之间的过渡期间,您不会遇到任何空字符串匹配问题。谁关心删除了多少空字符串?
sed
的正则表达式从左到右全局扫描模式空间。如果比赛之间存在重叠的可能性,那么它就不会很好地工作,因为它不会在g
全局中回溯。但我能想到的只有一种情况,这里处理。反正右边总是有空间的,左边也总有一些不是空间的。不过,有可能的是氮可能是您命名的单个字符分隔符之一,但在这种情况下,一个空格仍按应有的方式保留。
当它扫描时,它会根据模式检查输入 - 第一个可能匹配的是 3 字符的,第二个是 2 字符的,第三个是单个 - 空格(尽管这场比赛可能会持续任何时间)。
当发现其中任何一个时,sed
将用其自身替换前两个匹配中的一个 - 就像逾越节 - 但第三个将被完全删除。并且一口气。
答案2
也许是这样的:
perl -pe 's{((?:[ios=\%].|[\$^T\@!/()])+.)| }{$1}g'