Удалить интервал между буквами в обычном текстовом файле - PullRequest
0 голосов
/ 15 декабря 2018

У меня есть текстовый файл с множеством строк с межбуквенным интервалом, т.е.

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

Спасибо

Ответы [ 6 ]

0 голосов
/ 16 декабря 2018

Эту проблему можно решить многими разными способами.Самый простой способ, который я могу придумать, это просто удалить пробел перед строчными буквами.Я пытался использовать SED в качестве TrebuchetMS , упоминавшегося "у SED не было бдительности в их регулярных выражениях"

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'

Вывод: быстрый коричневый лис перепрыгивает через ленивую собаку enter image description here

0 голосов
/ 15 декабря 2018

С GNU awk для gensub ():

$ 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
0 голосов
/ 15 декабря 2018

Вот еще один вариант использования 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
0 голосов
/ 15 декабря 2018

Это может работать для вас (GNU sed):

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

Заменить все регистры пробела, за которым следует символ нижнего регистра, символом нижнего регистра, следующим за : в текущемлиния.Это решение работает в обратном направлении, пока не завершится неудачей, когда все случаи были учтены.

0 голосов
/ 15 декабря 2018

Я упомянул в комментариях, что вы можете использовать sed для этого.Попробовав это, я потерял надежду в sed, так как не мог найти обходных путей для работы в их регулярных выражениях.По-видимому, команда perl может анализировать регулярные выражения с помощью обходных путей.Если у вас есть команда perl, вы можете попробовать это

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

или

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

Что в мире означает этот забор?

Параметр perl -e указывает команде perl принять сценарий (это чудовищное регулярное выражение, которое вы видите сразу после него), и -p будет зацикливать сценарий вокруг файла.(Я не эксперт по Perl, поэтому мне нужно, чтобы кто-то дважды проверил это, я только посмотрел на perl -h для помощи.)

Теперь регулярное выражение.

s/<match>/<replace>/g следует *Синтаксис 1024 *.Это будет s earch g в общем для <match> и заменит его на <replace>.

Здесь совпадение было ([a-z])(?= |$), что говорит perl сопоставлять места с пробеламиза ним следует строчная буква (([a-z]), где [a-z] обозначает набор символов для сопоставления, а () обозначает группу захвата, используемую в разделе <replace>).

И , чтобы убедиться, что то, что следует, является либо пробелом, либо концом строки ((?= |$)), это [позитивный] взгляд в будущее, о котором я говорил ранее.Вертикальная черта подразумевает «или».Таким образом, смотритель будет искать пробел () "или" конец строки ($).Предварительный просмотр гарантирует правильное совпадение, не включая пробел / конец в совпадении.

Замена была \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, это будет включать Some, word и here.Таким образом, мы сопоставляем строчные буквы с пробелами спереди и сзади.Мы удаляем первый пробел, сопоставляя его, только заменяя букву, удаляя пробел.

Ограничения этого регулярного выражения

Если в вашем файле было

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

не так точно, как ответ gboffi в том смысле, что он соответствует после двоеточия, но все же регулярные выражения - короткий взлом ¯ \ _ (/) _ / ¯.

Дополнительная литература: Ссылка: Что означает это регулярное выражение?

0 голосов
/ 15 декабря 2018

Если то, что вы хотите, это то, что было предсказано TrebuchetMS в этом комментарии , нетрудно использовать awk:

$ awk -F: '{gsub(/ /,"",$2); gsub(/[A-Z]/," &",$2) ; print $1":"$2}' file.txt

в одну строкупрограмма ① разбивает строку на :, ② стирает все пробелы после :, ③ ставит пробел перед каждой заглавной буквой (также перед первой) и ④ печатает конкатенацию $1 (что предшествует :), a : и $2, то есть модифицированной второй части.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...