удалить произвольное количество совпадений с начала строки в расширении параметра zsh

Попробуйте это:

$ echo 'abc,def,12379,foo' | sed 's/,\([^,]*\),\([^,]*\)$/.\1.\2/'
abc,def.12379.foo

Это оставит строки с одной запятой (напримерfoo,bar). Это может быть или не быть тем, что вы хотите.

\(...\)группы захвата и \1, \2обратные ссылки в строке замены должны поддерживаться во всех версиях sed; Я тестировал вышеописанное на Unix v7.

ПС. Даже двойной sed из вашего вопроса должен работать на MacOS; может быть, ваша проблема в том, что строки заканчиваются CarriageReturns вместо LineFeeds?

1
09.02.2021, 22:57
2 ответа

Вы можете использовать расширенный оператор globx#:

x#
(Requires EXTENDED_GLOB to be set.) Matches zero or more occurrences of the pattern x. This operator has high precedence; ‘12#’ is equivalent to ‘1(2#)’, rather than ‘(12)#’. It is an error for an unquoted ‘#’ to follow something which cannot be repeated; this includes an empty string, a pattern already followed by ‘##’, or parentheses when part of a KSH_GLOB pattern (for example, ‘!(foo)#’ is invalid and must be replaced by ‘*(!(foo))’).

setopt extended_glob
stripped_var=${original_var##[[:blank:]]#}
2
18.03.2021, 22:31

Как @Freddy упомянул , с zshвы можете использовать шаблон [[:blank:]]#как эквивалент регулярного выражения [[:blank:]]*или ksh*([[:blank:]]).

Но в соответствии с POSIX вы также можете:

stripped_var=${orginal_var#"${original_var%%[![:blank:]]*}"}

Для эквивалента awk '{$1=$1};1', то есть удаления начальных и конечных пробелов и сжатия последовательностей пробелов в одно пространство, вы можете сделать:

var=$'  a    b\tc\t\td\t \n\n'
stripped_var=${${=var}}

(здесь $stripped_varстановится"a b c d"). То есть сделать$IFS-разбиение и снова привести к скаляру, который объединяет элементы с первым символом $IFS.

1
18.03.2021, 22:31

Теги

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