2013-08-06 7 views
1

Может ли кто-нибудь объяснить мне, как регулярное выражение работает в команде sed substitute.unix sed команда регулярное выражение

$ cat path.txt 
/usr/kbos/bin:/usr/local/bin:/usr/jbin:/usr/bin:/usr/sas/bin 
/usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin: 
/opt/omni/lbin:/opt/omni/sbin:/root/bin 

$ sed 's/\(\/[^:]*\).**/\1/g' path.txt 
/usr/kbos/bin 
/usr/local/sbin 
/opt/omni/lbin 

Из приведенной команды sed они использовали обратную ссылку и сохраняли концепцию оператора. Может ли кто-нибудь объяснить мне, как регулярное выражение, особенно /[^:] *, работает в команде substitute, чтобы получить только первый путь в каждой строке.

+1

'sed's /:.*// 'path.txt' будет более простой командой. – potong

ответ

5

Я думаю, что вы написали дополнительную звездочку * в вашем SED коде, поэтому он должен быть таким:

$ sed 's/\(\/[^:]*\).*/\1/g' file 
/usr/kbos/bin 
/usr/local/sbin 
/opt/omni/lbin 

Чтобы изменить разделитель поможет понять это немного лучше:

sed 's#\(/[^:]*\).*#\1#g' 

s#something#otherthing#g является базовой командой sed, которая ищет something и изменяет ее на otherthing по всему файлу.

Если вы делаете s#(something)#\1#g, то вы «сохраняете» это something, а затем можете распечатать его с помощью \1.

Следовательно, то, что он делает, это получить шаблон, подобный /[^:]*, а затем распечатать обратно. /[^:]* средства / and then every char except :. Таким образом, он получит / + всю строку, пока не найдет точку с запятой :. Он сохранит этот кусок строки и затем распечатает его.

Небольшие примеры:

# get every char 
$ echo "hello123bye" | sed 's#\([a-z]*\).*#\1#g' 
hello 

# get everything until it finds the number 3 
$ echo "hello123bye" | sed 's#\([^3]*\).*#\1#g' 
hello12 
+0

Хорошо, что, @ user2576028! Поскольку вы новичок здесь, помните, что вы можете отметить ответ, принятый, если ваша проблема уже решена. Вы можете сделать это, нажав на галочку рядом с ответом, чтобы переключить ее с полого на зеленый. См. [Справочный центр> Задать вопрос] (http://stackoverflow.com/helpcenter/someone-answers), если у вас есть какие-либо сомнения! – fedorqui

1
[^:]* 

в регулярном выражении будет соответствовать всем символам за : исключением, так что будет соответствовать до этого:

/usr/kbos/bin 

также не будет соответствовать этим,

/usr/local/bin 
/usr/jbin 
/usr/bin 
/usr/sas/bin 

A s, все они содержат символы, которые не являются :

.* соответствует любому символу, ноль или более раз.

Таким образом, это регулярное выражение [^:]*.*, будет соответствовать всем этим выражениям:

/usr/kbos/bin:/usr/local/bin:/usr/jbin:/usr/bin:/usr/sas/bin 
/usr/local/bin:/usr/jbin:/usr/bin:/usr/sas/bin 
/usr/jbin:/usr/bin:/usr/sas/bin 
/usr/bin:/usr/sas/bin 

Однако, вы получите только первое поле (то есть, /usr/kbos/bin, используя назад ссылки в sed), потому что, регулярное выход Экспрессии найдено самое длинное совпадение.

+0

очень полезная информация. Получил новую информацию о регулярном выражении. – Green