unix-删除(i)单个字符之间的空格和(ii)一个单词的X个以上连续实例

unix-删除(i)单个字符之间的空格和(ii)一个单词的X个以上连续实例,unix,awk,sed,Unix,Awk,Sed,我想 (i) 仅当字符为单个字符时,才替换字符之间的空格;i、 比如说 Down [Enter] p s -- a u x [Delete] 应该成为 Down [Enter] ps -- aux [Delete] (ii)删除连续重复超过X次的单词,直到任何其他不是该单词的东西出现为止,以便(假设X=2) 变成 [Delete] [Delete] ab initio [Delete] [Delete] ab definitio 谢谢 你没有得到很多回应。我认为主要原因是两个不同问题

我想

(i) 仅当字符为单个字符时,才替换字符之间的空格;i、 比如说

Down [Enter] p s -- a u x [Delete] 
应该成为

Down [Enter] ps -- aux [Delete] 
(ii)删除连续重复超过X次的单词,直到任何其他不是该单词的东西出现为止,以便(假设X=2)

变成

 [Delete] [Delete] ab initio [Delete] [Delete] ab definitio

谢谢

你没有得到很多回应。我认为主要原因是两个不同问题的结合,这两个问题都很重要。通常这有助于展示你自己的努力,但我认为你的努力可能已经思考了好几个小时“从哪里开始”

第一个问题,删除单个字符之间的空格,可以通过
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]
说明: 使用直接方法,在第一次更换后,u x将变为u x,而其他空间将被遗忘。您需要多次检查替换项,并记住
au x
中的字母
u
是原始字符串中的一个单态。
为了记住更换过的位置,我们使用
\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

欢迎来到SO。Stack Overflow是一个面向专业和热心程序员的问答网站。我们的目标是在你的问题中添加一些你自己的代码,以显示你自己为解决这个问题所做的研究工作。亲爱的沃尔特。你完全正确,我道歉。这是我在这里的第一篇文章。我提出的解决方案涉及python,而我更喜欢使用常用的unix工具。我正在查看tr,但没有找到解决方法。谢谢你的回复。(i)有一个问题,因为您的解决方案是从文件中删除所有的“r”,至少在我的sed中是这样(我在这里使用的是OpenBSD,而不是linux)。至于(ii),我现在就试试。(I)在我的
sed
中,回车
\r
起作用。它应该是一个唯一的字符,可能是测试的
Q
。尝试用control-v control-m替换\r。
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
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