我想
(i)仅当这些字符为单个时才替换字符之间的空格;即例如
Down [Enter] p s -- a u x [Delete]
应该成为
Down [Enter] ps -- aux [Delete]
(ii)删除连续重复超过X次的单词,直到出现任何其他不是单词的事物为止,以便(例如X = 2)
[Delete] [Delete] [Delete] [Delete] [Delete] [Delete] ab inition [Delete] [Delete] [Delete] [Delete] [Delete] [Delete] ab definitio
成为
[Delete] [Delete] ab initio [Delete] [Delete] ab definitio
谢谢!
答案 0 :(得分:0)
您没有得到很多答复。我认为主要原因是两个不同问题的组合,这两个问题都不是简单的。通常,它有助于显示您自己的努力,但是我理解您的努力可能已经花了几个小时“从哪里开始”了。
第一个问题,删除单个字符之间的空格,可以通过sed
中的循环来完成:
echo 'Down [Enter] p s -- a u x [Delete] ' |
sed -r ':a;s/( [^ ]|\r) ([^ ])( |$)/\1\2\r\3/;ta; s/\r//g'
Down [Enter] ps -- aux [Delete]
说明:
使用直接方法,a u x
将在第一次替换后更改为au x
,而其他空间将被忽略。您需要多次进行替换,并记住u
中的字母au x
是原始字符串中的单例。
为了记住已完成替换的位置,我们使用\r
(稍后将其删除)。
:a;
标签以返回下一次替换。
( [^ ]|\r)
后接字母或我们临时的\r
标记的空格
([^ ])
后接字母的空格
( |$)
空格或行尾
/\1\2\r\3/
用两个记住的字符代替,当它不是该行的最后一个字符时,插入一个特殊标记和一个空格。
ta
替换后返回到循环开始标记:a
s/\r//g'
删除我们的临时标记。
第二个问题也很困难。下一个解决方案很接近但不正确:
for (( X=2; X<8; X++)); do
echo "X=$X (incorrect solution)"
echo 'some some some some some some some some some some some input' |
sed -r 's/([^ ]+[ ]+)(\1{'${X}'})(\1+)/\2/g'
done
问题是当重复的字符串也出现在另一个位置时,如
some some some input some some some
或更糟糕的some some some input input input
。
我看不到sed
解决方案的简单修补,但是awk
在这里会有所帮助。
为了计算重复的字段,我的解决方案是将每个单词视为一条记录。
for (( X=2; X<8; X++)); do
echo "X=$X"
echo 'some some some some some some some some some some some input some some some some' |
awk -v x=$X 'BEGIN {RS="[ \n]"; ORS='\n'; repeated=1}
{ if (last==$0)
repeated++;
else
repeated=1;
}
{last=$0}
repeated <= x {print $0" "}
END {print "\n"}
'
done