Я думаю, что вы не можете не жадный
в поиск и замена
, вы можете сделать это только с удалением подстроки. Из ссылок на bash:
${параметр/шаблон/строка}
Шаблон расширяется для получения образца так же, как при расширении имени файла. Параметр расширяется, и самое длинное совпадение шаблона с его значением заменяется на строку. Если шаблон начинается с '/', все совпадения шаблона заменяются строкой. Обычно заменяется только заменяется только первое совпадение. Если шаблон начинается с '#', то он должен совпадать в в начале расширенного значения параметра. Если шаблон начинается с '%', то он должен совпадать с концом расширенного значения параметра. Если строка равна null, совпадения с шаблоном удаляются, а символ /, следующий за шаблоном, может быть опущен. может быть опущен. Если параметр имеет значение '@' или '', операция подстановки применяется к каждому позиционному параметру по очереди, и расширением является результирующий список. Если параметр является переменной массива подписанная символом '@' или '', операция подстановки применяется к каждому члену массива по очереди, а расширением является результирующий список список.
Чтобы решить это, вы должны установить extglob
:
shopt -s extglob
printf '%s\n' "${version/%.+([0-9])/.5}"
1.2.3.5
или использовать некоторые инструменты, такие как sed
или perl
:
printf '%s\n' "$version" | perl -pe 's/\.\d+$/\.5/'
1.2.3.5
alias
расширение — это просто подстановка текста, которая снова анализируется оболочкой, поэтому, когда вы делаете:
thead file.csv
Это просто заменено на:
head | cut -d, -f1- | column -s, -t file.csv
и интерпретируется снова.
Если бы вы написали:
<file.csv thead
или
cat file.csv | thead
или
{ thead; } < file.csv
Он бы работал так, как если бы его заменили на:
<file.csv head | cut -d, -f1- | column -s, -t
cat file.csv | head | cut -d, -f1- | column -s, -t
{ head | cut -d, -f1- | column -s, -t; } < file.csv
соответственно. В любом случае, как говорит @Kusalananda, для этого гораздо лучше использовать функции или сценарии, чем псевдонимы. Здесь я бы просто сделал:
thead() { head "$@" | cut -d, -f1- | column -s, -t; }
Например, вы можете сделать thead -n 12 file.csv file2.csv
.
Для чего-то более сложного, чем простая команда, используйте функцию оболочки вместо псевдонима:
thead () {
head -- "$1" | cut -d, -f1- | column -s, -t
}
Эта функция оболочки будет запускать head
со своим первым аргументом, а затем отправлять результат по конвейеру (, хотя, поскольку cut
получает все столбцы из-за -f 1-
, это часть, вероятно, можно удалить; Я оставлю это здесь, как это было в исходном конвейере ).
Или,
thead () {
head -- "$2" | cut -d "$1" -f1- | column -s "$1" -t
}
... чтобы иметь возможность использовать его как
thead ',' filename
Или даже, чтобы разрешить необязательный разделитель (и использовать запятую, если она не указана ),
thead () {
local delim=','
if [ "$#" -gt 1 ]; then
delim=$1
shift
fi
head -- "$1" | cut -d "$delim" -f1- | column -s "$delim" -t
}
Приведенное выше определение функции можно разместить везде, где вы обычно определяете псевдонимы.
Проблема с наличием конвейера в псевдониме заключается в том, что при использовании псевдонима с аргументом этот аргумент будет добавлен в конец конвейера, а не после первой команды в конвейере.
Руководство bash
содержит предложение
For almost every purpose, aliases are superseded by shell functions.