Мне пришло в голову, что я могу:
f_1() {
echo foo
}
f() { f_1 "$@"; }
g() {
f | sed -r 's/^|$/:/g' # random work
}
. m.sh
f_2() {
echo "$(f_1)bar"
}
f() { f_2 "$@"; }
g
Жаль, что это требует изменения m.sh
для добавления такого шаблона, но, по крайней мере, это позволяет избежать использования type
и eval
.
Необходимости вручную переопределять f()
для увеличения числа можно избежать, определив его один раз с первым определением как:
f() {
"$(last_version_of_function "${FUNCNAME[0]}")" "$@"
}
с помощью этих определений:
reverse_identifier_words() {
awk -F_ '
BEGIN {
OFS="_"
}
{
for (i = 1; i <= NF / 2; i++) {
t = $i
$i = $(NF - i + 1)
$(NF - i + 1) = t
}
print
}
'
}
last_version_of_function() {
declare -F \
| grep -Eo "\b${1}_[0-9]+\$" \
| reverse_identifier_words \
| sort -rn -t_ -k1 \
| head -n1 \
| reverse_identifier_words
}
Таким образом, e.sh
можно отменить, просто выполнив:
. m.sh
f_2() {
echo "$(f_1)bar"
}
g
Первое выражение s/^\(#\)//w /dev/stdout
удаляет то, что соответствовало бы второму выражению /^#/d
.
Вместо этого вы можете использовать
sed -i -e '/^#/{s///w /dev/stdout' -e 'd}' test
напр.
$ cat test
#this
#is
a
test
$ sed -i -e '/^#/{s///w /dev/stdout' -e 'd}' test
this
is
$ cat test
a
test