Это старый вопрос, который решался много раз. Просто для полноты картины :У меня была аналогичная проблема, но я хотел передать строки через канал в другую программу. Я использовал xargs .
-L max-lines
Use at most max-lines nonblank input lines per command line.
Trailing blanks cause an input line to be logically continued
on the next input line. Implies -x.
, так что cat f1.txt | xargs -L1
, кажется, выводит именно то, что вы хотите.
В операторе ${var/pattern/replacement}
ksh93 шаблон интерпретируется как шаблон подстановочного знака оболочки, а не регулярное выражение.
В ksh93 вы можете переключаться на базовые, расширенные или расширенные регулярные выражения с помощью ~(G)
, ~(E)
, ~(X)
соответственно, так что вы можете сделать:
var2=${var/~(E)_[0-9]{10}\.tgz$/}
Например. Или используйте его расширенные шаблоны глобусов:
var2=${var/%_{10}([0-9]).tgz/}
(то же, что иvar2=${var%%_{10}([0-9]).tgz}
)
bash
, как и zsh
, скопировали оператор ${var/pattern/replacement}
из ksh93, но его подстановочные операторы гораздо более ограничены. При включенной опции extglob
он поддерживает расширенные операторы ksh88
, но не более продвинутые из ksh93 и, в частности, не {x,y}(...)
.
Тем не менее, он поддерживает +(...)
. Так что вы могли бы сделать:
shopt -s extglob
var2=${var/%_+([0-9]).tgz/}
В bash
для расширенной поддержки регулярных выражений можно использовать =~
оператор его [[...]]
конструкции:
regexp='^(.*)_[0-9]{10}\.tgz$'
if [[ $var =~ $regexp ]]; then
var2=${BASH_REMATCH[1]}
else
var2=$var1
fi
Для полноты, хотя zsh
скопировал ${var/pattern/replacement}
ksh93 и поддерживает расширения подстановочных знаков ksh88 с опцией kshglob
, он имеет свои собственные расширенные операторы glob с опцией extendedglob
. С ними эквивалентом ERE {x,y}
является (#cx,y)
, так что вы можете сделать:
set -o extendedglob
var2=${var/%_[0-9](#c10).tgz}
(обратите внимание, что из трех оболочек zsh
— единственная, где [0-9]
соответствует только 0123456789. ksh93 и bash обычно совпадают еще по тысяче символов, таких как ⑱ и т. д. в современных локалях ).
В zsh
вы также можете выполнять сопоставление регулярных выражений с =~
.По умолчанию это ERE, но его можно изменить на PCRE с помощью опции rematchpcre
.
set -o rematchpcre
if [[ $var =~ '^(.*)_\d{10}\.tgz\z' ]]; then
var2=$match[1]
else
var2=$var
fi
(с ERE или PCRE, соответствует ли \d
или [0-9]
только 0123456789 или нет, зависит от локали и системной библиотеки регулярных выражений, используемой zsh, например, в bash ).
Если вы хотите получить только «резервную копию _пользовательских -данных»:
$ var="backup_user-data_2101220046.tgz"
$ echo "${var%_*}"
backup_user-data