Sed, не дающий первое вхождение шаблона

ls не имеет никакой опции сделать это, но одна из хороших вещей о Unix и Linux - то, что многоречивые и неэлегантные конвейеры могут легко быть превращены в сценарий оболочки, функцию или псевдоним. и они могут, в свою очередь, использоваться в конвейерах точно так же, как любая другая программа.

(ПРИМЕЧАНИЕ: существуют некоторые проблемы объема с функциями и псевдонимами. Сценарии доступны любому исполняемому файлу, который может считать и выполнить их. Псевдонимы и функции только доступны в текущей оболочке - хотя .profile/.bashrc подоболочки и т.д. может переопределить их и таким образом сделать их доступными. Кроме того, сценарий может быть записан на любом языке - включая bash/sh, awk, жемчуг, Python и других - какой бы ни каждый является лучшим для задания или что Вы являетесь самыми знакомыми с),

например.

alias lsf='find . -maxdepth 1 -type f -print0 | xargs -0r ls'

Я добавил xargs так, чтобы можно было использовать, используют все обычное ls опции, например. lsf -lrS

Поскольку это использует find, все обычно скрытые dotfiles будут отображены, и все имена файлов будут снабжены префиксом./-это о единственной разнице, которую Вы заметите.

Вы могли исключить точечные файлы с ! -iname '.*' но затем у Вас должно было бы быть две версии псевдонима - тот, который отобразил точечные файлы и тот, который не сделал.

alias lsf2='find . -maxdepth 1 -type f -a ! -iname '\''.*'\'' -print0 | xargs -0r ls'

С другой стороны, если lsf был сценарий, а не псевдоним, Вы могли проанализировать опции (возможно, с getopts или/usr/bin/getopt или подобный), и исключить dotfiles если -a присутствовал.

1
13.08.2013, 15:46
4 ответа

Использовать awk:

$ echo "inet addr:192.168.154.102 Bcast:192.168.154.255 Mask:255.255.255.0" | awk '{ split($2, a, ":"); print a[2] }'
192.168.154.102

Если абсолютно необходимо использовать sed, например:

echo "inet addr:192.168.154.102 Bcast:192.168.154.255 Mask:255.255.255.0" | sed 's#.*addr:\([0-9.]*\).*#\1#g'
192.168.154.102
1
27.01.2020, 23:29
  • 1
    является там любым способом, которым я могу получить первое вхождение с помощью sed –  munish 13.08.2013, 15:51
  • 2
    Используя sed, нет, потому что нет никакого способа сделать * нежадный. –  lgeorget 13.08.2013, 15:56
  • 3
    @munish я обновил свой ответ. –  Adrian Frühwirth 13.08.2013, 15:56
  • 4
    На заметке на полях, если Вы имеете GNU grep Вы могли также сделать a grep -oP 'addr:\K[0-9.]+' –  Adrian Frühwirth 13.08.2013, 16:02

Проблема состоит в том, что звездочка как регулярное выражение является максимально жадной, и она соответствует как можно скорее. Это просто означает это ".*" будет соответствовать на первой строке "почти всему"

inet addr:192.168.154.102 Bcast:192.168.154.255 Mask:2

и на втором

inet addr:127.0.0.1 Mask:25

и таким образом, это печатает то, что остается и что Вы получили.

В Вашем случае я попытался бы быть более конкретным как использование ":" как разделитель или некоторый префикс как "addr": или можно удалить все символы, но не точки и цифры, поскольку адрес IPv4 состоит только из них. Можно попробовать эту команду:

tr -cd '[0-9. ]' < YOUR_FILE

Можно затем продолжить обработку вывода.

1
27.01.2020, 23:29

Использовать

sed -n '/inet addr:/s/[^:]\+:\(\S\+\).*/\1/p'

Попробуйте это от командной строки

ifconfig | sed -n '/inet addr:/s/[^:]\+:\(\S\+\).*/\1/p'

Вывод

192.168.154.102
127.0.0.1
1
27.01.2020, 23:29

Если Вы только хотите к grep определенным шаблонам, почему бы не использовать

awk -F'[: ]' '/inet addr:/{ print $4}' file
0
27.01.2020, 23:29

Теги

Похожие вопросы