2014-02-17 3 views
2

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

Учитывая строку "1abc2abcd3efghi10z11jkl100pqrs", что команда, которую вы используете, чтобы получить следующий результат -

"1 аЬс 2 ABCD 3 efghi 10 г 11 JKL 100 ФХЦЧ"

Спасибо заранее.

ответ

4

Вот еще один - но простой - способ думать об этом:

echo "1abc2abcd3efghi10z11jkl100pqrs" | \ 
sed -r 's/([0-9])([a-zA-Z])/\1 \2/g; s/([a-zA-Z])([0-9])/\1 \2/g' 
  • добавить пробелы между цифрами-буквой строки & буквенно-цифровая строка
  • () должен захват группы и \1 и \2 - для возврата первой и второй захваченных групп
+0

Спасибо, сэр. Это сработало. – user1149518

3

я выбрал бы над :

echo "1abc2abcd3efghi10z11jkl100pqrs" | sed 's/[0-9]\+/ & /g; s/^[ ]//; s/[ ]$//' 

Он окружает каждую серию из цифр с пробелами, а затем удаляет (возможно) начальные и конечные из них.

Это дает:

1 abc 2 abcd 3 efghi 10 z 11 jkl 100 pqrs 
+0

Thank много. Оно работает. – user1149518

+0

@ mklement0: Спасибо за редактирование. – Birei

+0

@Birei: Добро пожаловать - на самом деле немного испортил это; надеюсь, исправлено сейчас ... – mklement0

3
echo 1abc2abcd3efghi10z11jkl100pqrs | \ 
    sed -r -e 's/([[:digit:]]+)/ \1 /g' -e 's/^ *//g' -e 's/ *$//g' 

Возьмите выражение -e 's/([[:digit:]]+)/ \1 /g' первый.

Круглые скобки вокруг [[:digit:]]+ «захватывают» каждую последовательность из одной или нескольких цифр. Так как это первая группа захвата, она упоминается в подстановке \1 (тогда есть место до и после:  \1 ).

gsed выполняет эту замену «глобально» на вход.

-r перед выражением говорит sed использовать расширенные регулярные выражения.

В двух других выражений »(каждое выражение имеет -e до того, чтобы показать, что это выражение): -e 's/^ *//g' будет удалить ведущие пробелы, и -e 's/ *$//g' будет удалить конечные пробелы.

+0

Большое спасибо. Оно работает. – user1149518

+1

+1 для объяснения; Пользователи OSX: используйте '-E' вместо' -r'. – mklement0

4

GNU sed С:

$ echo "1abc2abcd3efghi10z11jkl100pqrs" | sed -e 's/[0-9]\+/ & /g' -e 's/^ \| $//' 
1 abc 2 abcd 3 efghi 10 z 11 jkl 100 pqrs 

С awk:

$ echo "1abc2abcd3efghi10z11jkl100pqrs" | awk '{gsub(/[0-9]+/," & ",$0); $1=$1}1' 
1 abc 2 abcd 3 efghi 10 z 11 jkl 100 pqrs 
  • gsub с заменой всех чисел с пространством до и после него.
  • $1=$1 повторно вычислить всю строку и добавить OFS (по умолчанию одного пространства)
+0

Большое спасибо. Оно работает. – user1149518

+0

@ user1149518 Добавлено также решение 'awk'. –

1

Использование perl:

echo 1abc2abcd3efghi10z11jkl100pqrs | perl -F'(\d+)' -ane \ 
    '$F[0] and print "@F\n" or print "@F[1..$#F]"' 

Некоторые объяснения:

  • вместе говорит Perl для разделите каждую строку ввода и поместите полученные поля в массив @F.
  • -F указывает разделитель одной или нескольких цифр для использования с для разделения ввода. Скобки приводят к тому, что сами разделители хранятся в массиве, а не только строки, которые они разделяют.
  • -e указывает код для запуска после считывания каждой строки. Мы просто хотим распечатать содержимое @F с разделителем полей по умолчанию (пробел), используемым для разделения элементов массива. Комбинация and...or используется для игнорирования первого поля, если оно пустое, как это будет, если строка ввода начинается с разделителя.
+0

Спасибо. Оно работает. – user1149518

+0

Благодаря ALL. Я думаю, что это своего рода оптимальный результат, который я получил из всех ваших ответов! $ echo "1abc2abcd3efghi10z11jkl100pqrs" | sed 's/[a-z] \ +/&/g' 1 abc 2 abcd 3 efghi 10 z 11 jkl 100 pqrs – user1149518

Смежные вопросы