LINUX.ORG.RU

sed, awk: повторить символ n раз

 , ,


0

4

Добрый вечер! В сети очень много примеров удаления дубликатов символов с помощью sed. А как сделать обратную операцию? То есть заменить символ (допустим пробела) - n такими же. Дело в том, что sed не видит регулярное выражение, если оно находится во второй части substitution, т.е. нельзя написать regexp вида:

sed -e "s/ / \{10\}/g"

Дело в том, мне что нужно менять один пробел n такими же во всем тексте и желательно однострочником на sed или awk или им подобными, так как с bash и циклами я не работаю, а с unixutils.

Да, есть, конечно, простой вариант замены:

sed -e "s/ /          /g"
но он не годится, так как количество пробелов я подставляю в виде числовой переменной %0 esPICK% в кронтабе nncron, поэтому желательно наличие в однострочнике именно числа (цифры) повторов.


По-моему в sed-е нету циклов. Это же потоковый редактор, а не язык программирования.

А так, не проще-ли делать циклы делай через bash.

anonymous
()
#!/bin/sh
NUMSPACES=13;
SPACES=$( printf "%${NUMSPACES}s" )

echo 'a b' | sed -e "s/ /${SPACES}/"
surefire ★★★
()

Сгенерировать (повторить) символ N раз

## символ | сто раз
printf '|%.0s' {1..100} | wc -c

$ N=19
$ eval "S=\$(printf '|%.0s' {1..$N})"
$ echo $S
|||||||||||||||||||
futurama ★★★★★
()
Ответ на: комментарий от futurama

Судя по всему и не должно:

The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and pathname expansion.

xaizek ★★★★★
()
Ответ на: комментарий от futurama

так как с bash и циклами я не работаю, а с unixutils.

{1..100}
python: not a shell builtin

будешь понтоватся, когда (хотя бы) научишься отличать «shell bultin» от башизмов

anonymous
()

Дело в том, мне что нужно менять один пробел n такими же во всем тексте и желательно однострочником на sed или awk или им подобными

awk, переменную можно передать так: "-v var=42"; есть sprintf (ну и про gsub все в курсе)

anonymous
()
Ответ на: комментарий от anonymous

будешь понтоватся, когда (хотя бы) научишься отличать «shell bultin» от башизмов
от башизмов
башизмов

Чавой?

Zmicier ★★★★★
()
Ответ на: комментарий от anonymous

Ты переоцениваешь его ванговательные способности.

anonymous
()
Ответ на: комментарий от anonymous

будешь понтоватся, когда (хотя бы) научишься отличать «shell bultin» от башизмов

Чавой

Возможностей bash, которых нет в стандарте и других оболочках (dash, busybox ash, zsh в режиме эмуляции sh)

И что же здесь по-вашему надо было от них отличать?

Что не так?

Все. И форма наезда, и суть. И слово идиотское.

Zmicier ★★★★★
()
Последнее исправление: Zmicier (всего исправлений: 1)
Ответ на: комментарий от anonymous

Ха! Никогда не задумывался о фонетической стороне, но теперь пожалуй соглашусь с вами насчет глупости звучания.

Zmicier ★★★★★
()

Самое наипростейшее, быстрое и изящное решение:

echo ABCD | sed s/A/$(printf %3s | tr " " "X")/
И, насколько я помню, полностью POSIX-совместимое. Ты бы рассказал, в каком кусочке кода такое понадобилось. А то у меня есть ещё несколько интересных штук, в зависимости от области применения.

mr_Heisenberg
()
Ответ на: комментарий от mr_Heisenberg

Не получилось, даже экранировал кавычки:

c:\nncron>echo ABCD | sed -e "s/A/$(printf %3s | tr \" \" \"X\")/
$(printf %3s | tr " " "X")BCD

c:\nncron>echo ABCD | sed -e "s/A/$(printf %3s | tr \" \" \"X\")/
$(printf %3s | tr " " "X")BCD

printf установлен.

xseed
() автор топика
Ответ на: комментарий от doushiyou

Не получается, вообще не пойму как под виндой пользоваться printf:

c:\nncron>printf "|%.0s" {1..100}
|
c:\nncron>printf "|%.0s" "{1..100}"
|
c:\nncron>printf "|%.0s" "\{1..100\}"
|
c:\nncron>printf "|%\.0s" {1..100}
|printf: %\: invalid directive

Вот эти выражения работают:

c:\nncron>printf "%.s%s\n" "Bonjour" "Hello"
Hello
c:\nncron>printf "Surname: %s\nName: %s\n" "$SURNAME" "$LASTNAME"
Surname: $SURNAME
Name: $LASTNAME

xseed
() автор топика
Ответ на: комментарий от xseed

Потому что их не надо тут экранировать. А printf - стандартная unix команда. Она не нуждается в установке))

mr_Heisenberg
()
Ответ на: комментарий от xseed

Дык ты ещё и в окнах... Ох щит... Прости, но я могу помочь только в святом linux.

mr_Heisenberg
()

так как с bash и циклами я не работаю, а с unixutils.

$ cat repeat_char.c

#include <stdio.h>

int main(int argc, char *argv[]) {
    int i;
    int mul = atoi(argv[2]);

    for (i=0; i<mul; i++) {
        putchar(*argv[1]);
    }
   return 0;
}

$ gcc -O2 repeat_char.c -o repeat_char
$ ./repeat_char 'X' 10
XXXXXXXXXX
$ ls -l repeat_char
-rwxr-xr-x 1 user group 6992 Month Day 00:00 repeat_char

futurama ★★★★★
()
Ответ на: комментарий от xseed

не получилось

Опечатки несущественны, главное, чтобы идея понятна.

DonkeyHot ★★★★★
()
Ответ на: комментарий от mr_Heisenberg

А смысл на это дрочить? Сишный бинарник минималистичнее и быстрее, перло-питоновая скриптота менее костыльна.

anonymous
()
Ответ на: комментарий от Zmicier

А про рекурсию с отрицанием забыли) Что-то проснулся сегодня и мысля пришла, почему бы не сделать так:

sed -e ":a;/\t\{10\}/!s/\t/&&/g;ta"
и действительно, работает

xseed
() автор топика
Ответ на: например так от DonkeyHot

Или если нужно заменить конкретный TAB, например второй:

sed -e ":a;/\t\{10\}/!s/\t/&&/2;ta"
Всем спасибо за ответы.

xseed
() автор топика
Ответ на: комментарий от xseed

Только такая конструкция не будет работать, если в строке уже есть 10 TAB.

xseed
() автор топика
Ответ на: комментарий от xseed

Точно, в другой теме (2 таба) рассказал тебе о цикле в sed. Хотел было попробовать этот способ, но был пьян, у меня ничего не вышло, лёг спать и успешно забыл об этом:D

mr_Heisenberg
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.