Sysop: | Amessyroom |
---|---|
Location: | Fayetteville, NC |
Users: | 28 |
Nodes: | 6 (0 / 6) |
Uptime: | 102:50:41 |
Calls: | 452 |
Files: | 1,050 |
D/L today: |
118 files (54,333K bytes) |
Messages: | 96,694 |
Posted today: | 1 |
I'm pondering about creating a functional processing pipe, depending
on program parameters, and whether that's possible to achieve without
using 'eval'.
Say, the program is called "filter" and may accept 0..N parameters and depending on the set of parameters the respective pipe functionality
shall be defined like
filter => cat
filter p1 => cat | func p1
filter p1 p2 => cat | func p1 | func p2
filter p1 p2 ... pN => cat | func p1 | func p2 | ... | func pN
where "func" is working as filter and accepts exactly one parameter.
On 2025-05-07, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
I'm pondering about creating a functional processing pipe, depending
on program parameters, and whether that's possible to achieve without
using 'eval'.
Say, the program is called "filter" and may accept 0..N parameters and
depending on the set of parameters the respective pipe functionality
shall be defined like
filter => cat
filter p1 => cat | func p1
filter p1 p2 => cat | func p1 | func p2
filter p1 p2 ... pN => cat | func p1 | func p2 | ... | func pN
where "func" is working as filter and accepts exactly one parameter.
The problem is that the number of pipes on the right hand side
depends on the number of arguments.
The number of pipes in a command pipe is a property of syntax;
it is something that needs eval.
If you're interested in being able to make this kind of code
transformation, perhaps you should start a project to add macros to a
shell. (An educated guess informs me that you'd likely choose Korn).
Macros avoid extra eval by taking advantage of the result of the
substitution being "naturally thrown into the path of the evaluator",
just like any other code that is not expanded by a macro.
I'm pondering about creating a functional processing pipe, depending
on program parameters, and whether that's possible to achieve without
using 'eval'.
Say, the program is called "filter" and may accept 0..N parameters and depending on the set of parameters the respective pipe functionality
shall be defined like
filter => cat
filter p1 => cat | func p1
filter p1 p2 => cat | func p1 | func p2
filter p1 p2 ... pN => cat | func p1 | func p2 | ... | func pN
where "func" is working as filter and accepts exactly one parameter.
(Because of reservations I have with 'eval' and quoting I'd like to
avoid that 'eval' indirection if possible.)
On 2025-05-07, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
I'm pondering about creating a functional processing pipe, depending
on program parameters, and whether that's possible to achieve without
using 'eval'.
Say, the program is called "filter" and may accept 0..N parameters and
depending on the set of parameters the respective pipe functionality
shall be defined like
filter => cat
filter p1 => cat | func p1
filter p1 p2 => cat | func p1 | func p2
filter p1 p2 ... pN => cat | func p1 | func p2 | ... | func pN
where "func" is working as filter and accepts exactly one parameter.
(Because of reservations I have with 'eval' and quoting I'd like to
avoid that 'eval' indirection if possible.)
For a limited number of arguments, you could do it with a switch,
enumerating the variations. I can see the utility of such a feature.
It seems that you could do this with a small wrapper program (in your favorite progframming language) activating the shell once the pipeline
has been constructed.
I would like to have this king of feature wrapped around grep in order
to do compounded keyword searches, but it's not a high priority.
Lars
On 07.05.2025 14:58, Lars Poulsen wrote:
I would like to have this king of feature wrapped around grep in order
to do compounded keyword searches, but it's not a high priority.
I recall I've done such with 'grep', simply transforming the
shell arguments to a 'grep' argument. It was simple, like
x=$*
grep -E '('"${x// /|}"')'
I'm pondering about creating a functional processing pipe, depending
on program parameters, and whether that's possible to achieve without
using 'eval'.
Say, the program is called "filter" and may accept 0..N parameters and depending on the set of parameters the respective pipe functionality
shall be defined like
filter => cat
filter p1 => cat | func p1
filter p1 p2 => cat | func p1 | func p2
filter p1 p2 ... pN => cat | func p1 | func p2 | ... | func pN
where "func" is working as filter and accepts exactly one parameter.
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
I'm pondering about creating a functional processing pipe, depending
on program parameters, and whether that's possible to achieve without
using 'eval'.
Say, the program is called "filter" and may accept 0..N parameters and
depending on the set of parameters the respective pipe functionality
shall be defined like
filter => cat
filter p1 => cat | func p1
filter p1 p2 => cat | func p1 | func p2
filter p1 p2 ... pN => cat | func p1 | func p2 | ... | func pN
where "func" is working as filter and accepts exactly one parameter.
You don't really need the initial cat except when there are no
arguments.
Using this fact, and provided you don't mind an extra cat
command at the end of the pipe,
does this do what you want:
#!/bin/bash
function recurse
{
if [[ $# -ge 1 ]]
then grep "$1" | (shift; recurse "$@")
else cat
fi
}
recurse "$@"
(I'm using grep and the filer here because it permits simple testing.)
I think one could remove the final cat command, but I'm in hurry to
catch the shops!
function recurse
{
if [[ $# -ge 1 ]]
then grep "$1" | (shift; recurse "$@")
else cat
fi
}
I certainly need a "transparent" (idempotent) function if there are no arguments provided, so a 'cat' is what I need in that case. (An empty
output would definitely be wrong for me.) And the unnecessary 'cat' at
the pipe end(s) is an acceptable unimportant degradation (for me). But
if you have an idea how to remove it... :-)
On 2025-05-07, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
function recurse
{
if [[ $# -ge 1 ]]
then grep "$1" | (shift; recurse "$@")
else cat
fi
}
I certainly need a "transparent" (idempotent) function if there are no
arguments provided, so a 'cat' is what I need in that case. (An empty
output would definitely be wrong for me.) And the unnecessary 'cat' at
the pipe end(s) is an acceptable unimportant degradation (for me). But
if you have an idea how to remove it... :-)
recurse()
{
case $# in
0) cat ;;
1) grep "$1" ;;
*) grep "$1" | (shift; recurse "$@") ;;
esac
}