Есть ли способ реализовать/использовать лямбда-функции в bash? Я думаю о чем-то вроде:
$ someCommand | xargs -L1 (lambda function)
Есть ли способ реализовать/использовать лямбда-функции в bash? Я думаю о чем-то вроде:
$ someCommand | xargs -L1 (lambda function)
Я не знаю, как это сделать, но вы можете выполнить то, что вы пытаетесь сделать, используя:
somecommand | while read -r; do echo "Something with $REPLY"; done
Это также будет быстрее, так как вы не будете создавать новый процесс для каждой строки текста.
[EDIT 2009-07-09] Я сделал два изменения:
-r
для отключения обработки обратной косой черты - это означает, что обратные косые черты на входе будут переданы без изменений.X
) в качестве параметра read
, мы позволяем read
присваивать его переменной по умолчанию REPLY
. Это имеет приятный побочный эффект для сохранения ведущих и конечных пространств, которые в противном случае удаляются (хотя внутренние пространства сохранены).Из моих наблюдений вместе эти изменения сохраняют все, кроме буквальных символов NUL (ASCII 0) на каждой строке ввода.
[EDIT 26/7/2016]
Согласно комментарию Evi1M4chine, установка $IFS
в пустую строку перед запуском read X
(например, с помощью команды IFS='' read X
) также должна сохранять пробелы в начале и конце при сохранении результата в $X
, что означает вы не должны использовать $REPLY
.
если вам нужны истинные функции, а не только каналы или циклы while (например, если вы хотите передать их, как если бы они были данными) Id просто не делал лямбда и определял фиктивные функции с повторяющимся фиктивным именем, чтобы использовать сразу же, и выбросить потом. Например:
# An example map function, to use in the example below.
map() { local f="$1"; shift; for i in "[email protected]"; do "$f" "$i"; done; }
# Lambda function [λ], passed to the map function.
λ(){ echo "Lambda sees $1"; }; map λ *
Как и в правильных функциональных языках, нет необходимости передавать параметры, так как вы можете обернуть их в закрытие:
# Let’s say you have a function with three parameters
# that you want to use as a lambda:
# (As in: Partial function application.)
trio(){ echo "$1 Lambda sees $3 $2"; }
# And there are two values that you want to use to parametrize a
# function that shall be your lambda.
pre="<<<"
post=">>>"
# Then you’d just wrap them in a closure, and be done with it:
λ(){ trio "$pre" "$post" "[email protected]"; }; map λ *
Id утверждает, что его еще меньше, чем все другие решения, представленные здесь.
Как насчет этого?
somecommand | xargs -d"\n" -I{} echo "the argument is: {}"
(предполагается, что каждый аргумент является строкой, в противном случае - разделителем)
если вы хотите использовать только xargs (например, параллельную опцию -P N
) и только bash в качестве функционального кода, тогда bash -c
может использоваться как параметр для xargs.
seq 1 10 | tr '\n' '\0' | xargs -0 -n 1 bash -c 'echo any bash code $0'
tr и -0 используются здесь, чтобы отключить любые замены параметров xargs.
Да. Можно передать строковую переменную, представляющую вызов команды, а затем выполнить команду с помощью eval.
Пример:
command='echo howdy'
eval "$command"
Уловка eval уже упоминалась, но вот мой расширенный пример закрытия bash:
#!/usr/bin/env bash
set -e
function multiplyBy() {
X="$1"
cat <<-EOF
Y="\$1"
echo "$X * \$Y = \$(( $X * \$Y ))"
EOF
}
function callFunc() {
CODE="$1"
shift
eval "$CODE"
}
MULT_BY_2='multiplyBy 2'
MULT_BY_4='multiplyBy 4'
callFunc "$MULT_BY_2" 10
callFunc "$MULT_BY_4" 10
PS Я только что придумал это для совершенно другой цели и просто искал в Google, чтобы узнать, использует ли это sb. Мне действительно нужно было оценить функцию многократного использования в контексте (оболочке) основного скрипта.