2012-06-29 4 views

ответ

23

Там нет причин, чтобы использовать внешний инструмент, как СЭД для этого; Баш может сделать это внутренне, using parameter expansion:

Если символ, который вы хотите обрезать после того, как :, например:

$ str=foo_bar:baz 
$ echo "${str%%:*}" 
foo_bar 

Вы можете сделать это в обоих жадных и не жадных способами:

$ str=foo_bar:baz:qux 
$ echo "${str%:*}" 
foo_bar:baz 
$ echo "${str%%:*}" 
foo_bar 

Особенно, если вы вызываете это внутри жесткой петли, начинаете новый процесс sed, записываете в процесс, читаете его вывод и ожидаете его выхода (чтобы извлечь его PID) могут быть существенными накладными расходами, которые делают все ваши внутренняя обработка в bash w не имеет.


Теперь - часто, когда хотят, чтобы сделать это, что вы могли бы действительно хотите, чтобы разделить переменную на поля, которые лучше сделать с read.

Например, допустим, что вы читаете строку из /etc/passwd:

line=root:x:0:0:root:/root:/bin/bash 
IFS=: read -r name password_hashed uid gid fullname homedir shell _ <<<"$line" 
echo "$name" # will emit "root" 
echo "$shell" # will emit "/bin/bash" 

Даже если вы хотите обработать несколько строк из файла, это тоже может быть сделано с Баш в одиночку и нет никаких внешних процессов:

while read -r; do 
    echo "${REPLY%%:*}" 
done <file 

... будет излучать все, вплоть до первого : из каждой строки file, не требуя какой-либо доб которые будут запущены.

8

Что вы ищете на самом деле очень просто:

sed 's/A.*//' 

Где A отмечает специфику. Обратите внимание, что он чувствителен к регистру, если вы хотите, чтобы поймать несколько символов использовать

sed 's/[aAbB].*//' 
2

Если текст содержит текст, как и в

TEXT=beforexafter 

и специфика происходит (например), чтобы быть x, то

echo "${TEXT%x*}" 

делает то, что вы хотите.

колотить, "$TEXT" или "${TEXT}" целая beforexafter, но "${TEXT%xafter}" просто before, с xafter сколов конца. Чтобы отрубить x и все, что может последовать за ним, пишет "${TEXT%x*}".

Существует также "${TEXT%%x*}", кстати. Это отличается от другого только при наличии более одного x. С %% Баш отбивает все x, тогда как с % он отбивает только от последних x. Вы можете помнить об этом, наблюдая свободно, что дольше %% отбивает больше текста.

Вы можете сделать то же самое с Sed, конечно, если вы предпочитаете:

echo "$TEXT" | sed 's/x.*//' 
+2

Пожалуйста, поставьте кавычки расширения - 'Эхо $ Text' будет делать строковое расщеплению, так что если' Text' содержит '$ 'foo \ t \ tbar \ nbaz'', он выйдет просто как 'foo bar baz', тогда как' echo' $ TEXT '' не проявляет этого недостатка. (Сохранение переменной переменной «все-шапки», не относящейся к среде, также немного неудачно, лучше всего сделать их более строгими, чтобы избежать конфликтов пространства имен с переменными среды и встроенными функциями). –

+0

@CharlesDuffy: Вы правы насчет котировок: упущение их - моя дурная привычка, с которой я должен реформироваться. Что касается всех шапок, вы делаете интересный момент, с еще более интересным объяснением. Я подозреваю, что ваш совет относительно крышек хорош. – thb

+1

Не вопрос, а связанный. Чтобы получить 'after' запустите' echo '$ {TEXT # * x} "' –