LINUX.ORG.RU

sed в sh

 ,


1

1

В общем вот:

~ $ echo "qwer=asdf" | sed 's/(.*)=/\1/'
qwer=asdf
~ $ echo "qwer=asdf" | sed 's/(.*)=/&1/'
qwer=asdf
~ $ echo "qwer=asdf" | sed 's/(.*)=/$1/'
qwer=asdf
~ $ 

Совсем запутался. Подскажите, пожалуйста, как выдернуть первую часть строки (до знака «=»)? (И потом вторую часть.)


Забыли либо -r, либо экранировать скобки, чтобы они приобрели своё специальное значение.

AITap ★★★★★
()

как выдернуть первую часть

...\1/'

или s/=.*//

А вообще ${var%=*} / ${var#*%} будет более sh-идиоматично.

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

Забыли либо -r, либо экранировать скобки, чтобы они приобрели своё специальное значение.

Экранирование помогло. Спасибо.

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

А с чего ты взял, что у тебя bash а не busybox/etc?

Именно он. busybox, v 1.14. Просто домашняя машина выдала тот же результат, поэтому я не стал уточнять что используется он.

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

или s/=.*//

блин. Точно ) .

А вообще ${var%=*} / ${var#*%} будет более sh-идиоматично.

Спасибо. Разберусь.

anonymous
()

В rc достаточно было бы сделать ifs='=' nameval=`{read}, но в баше всё не так просто.
Можно сделать awk -F'=' '{print $1}'.

quantum-troll ★★★★★
()
Ответ на: комментарий от quantum-troll

но в баше всё не так просто

Кэп намекает, что вы плохо знаете баш %) :

#!/bin/bash

IFS==
read a b < <(echo "1=2")

echo "$a:$b"

В субшелле можно в любом sh-like: <cmd> | { IFS=..; read ... ; }

В текущем процессе: если fish / zsh, можно <cmd> | read ... ; в баш, как приведено выше - финт через process-redirection.

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

В субшелле можно в любом sh-like

Добавлю, что если из известной строки, а не команды, то без субшелла: read .. << EOF ...

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

Кэп намекает, что вы плохо знаете баш %) : …

Я очень плохо знаю баш.

Можно поподробнее про приведённый в примере блок кода (с IFS)? Приведи, пожалуйста, пример как его использовать (как он работает и почему)? Или мне лучше пойти на bash scripting guide?

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

read a b < <(echo «1=2»)

так как баш, берем его ман в районе read:

the first word is assigned to the first name, the second word to the second name ... The characters in IFS are used to split the line into words.

«<» - перенаправление из файла или дескриптора

«<(..)» - это в районе Process Substitution: вкратце, баш выполняет команду и заменяет конструкцию на /dev/fd/.. , в котором будет ее вывод (только для последовательного чтения, lseek не покатит)

Но последний башизм, без особого повода - лучше не использовать.

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

IFS==
read a b < <(echo «1=2»)
echo «$a:$b»

Красиво и наглядно.

Получается, так можно и несколько переменных сразу присвоить. Правда, остаток фразы в конце присваивается целиком, без учёта разделителей.

$ IFS="= .,; +-_"
$ read a b c d f < <(echo "однажды+в;студёную_зимнюю по..ру")
$ echo "$a:$b:$c:$d:$f"
однажды:в:студёную:зимнюю:по..ру

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

Красиво и наглядно

Амбивалентное ощущение, с одной стороны heredoc на 2 строки больше, с другой - все-таки башизм.

И echo для примера, если строка известна - лучше другой вариант: <<< "... "

anonymous
()
Ответ на: комментарий от justAmoment
% ifs='= .,; +-_' ifs=$ifs^`{echo} list=`{echo 'однажды+в;студёную_зимнюю по..ру'} echo ','^$list
,однажды ,в ,студёную ,зимнюю ,по ,ру

В rc это работает полностью, так как он полноценно умеет в списки.
Кроме того, ifs можно выставить локально, в отличие от баша.

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

так как он полноценно умеет в списки

Ну это уже другой вопрос, вроде примерно, как в tcl?

ifs можно выставить локально, в отличие от баша

Боюсь вас удивить, но:

IFS="=" read a b <<< "1=2"
read c d <<< "3 4"

echo "$a:$b:$c:$d"
anonymous
()
Ответ на: комментарий от anonymous

Боюсь вас удивить, но:

Да, но работает далеко не во всех случаях. Кроме того

% IFS='*' for I in `echo "a*b*c"`; do echo "$I+" ; done
zsh: parse error near `for'
В баше так же не работает.

вроде примерно, как в tcl?

В tcl плоские списки?

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

далеко не во всех случаях

Тем не менее, нельзя сказать, что локально нельзя изменить, и в любом случае, разве ф-ия c local не поможет?

temp() {
  local IFS="*"
  for I in `echo "a*b*c"`; do echo "$I+" ; done
}

temp

for i in `echo "a*b"`; do echo "$i"; done

Конечно, уже не всегда лучше временного изменения IFS.

В tcl плоские списки?

Нет, просто показалось, что rc позволяет гибче работать с ними, вплоть до вложенных. Это только для выхлопа? '{..} - аналог «${(f)$(..)}» из zsh?

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

`{} выполняет команду и возвращает список, руководствуясь ifs.
(a b (c d)) — то же самое, что и (a b c d). $l(n) возвращает элемент, $l(n-m) — список, $#l — кол-во элементов в списке, $«l — строку.
Впрочем, смотри ман, он короткий и удобочитаемый: http://dev.man-online.org/man1/plan9-rc/

и в любом случае, разве ф-ия c local не поможет?

Почему скрипты на баше состоят из костылей чуть менее, чем полностью?

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

http://dev.man-online.org/man1/plan9-rc/

Боюсь не найду преимущества достаточно весомыми для освоения нового синтаксиса, здесь местами костыли, но все-таки над стандартом.

состоят из костылей чуть менее, чем полностью?

С каких пор локальная ф-ия - костыль?) И да, если вы принимаете меня за апологета bash-а - вы ошибаетесь. Предпочитаю что-нибудь ближе к posix (тот же dash). Редкое искючение: http://rosettacode.org/wiki/Sierpinski_carpet#UNIX_Shell

Ввиду меньшей распостраненности на rc в среднем пишут более опытные люди, так что напрямую сравнивать нельзя. Лучше несколько (не специально подобранных примеров), где аналог на (ba)sh будет выглядеть костыльным. Когда-то переписывал ssam, вроде не сильно хуже выглядит.

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