Вы не получили много ответов. Я думаю, что главной причиной является сочетание двух разных вопросов, оба нетривиальных. Обычно это помогает продемонстрировать ваши собственные усилия, но я понимаю, что ваши усилия могли часами думать, «с чего начать».
Первый вопрос, устранение пробелов между одиночными символами, может быть выполнен с помощью цикла в 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