所以我试图找到一个 bash/shell 脚本的模板,它本质上运行一个命令,让我们使用输入“X”将其称为“command1”,然后在其本身上使用 command1 的输出......但在一个循环中。
这是一个现实世界的例子:
echo "hello" | cut -c2-
这将删除输入字符串开头的第一个字符并输出:
ello
现在,上面只是一个例子来说明上面提到的模板。按照这个例子,我该如何使用命令1输出:
echo "hello" | cut -c2-
但作为输入,在循环中,要么无限循环,要么直到只剩下一个字节/字符。
这样我就不需要复制/粘贴输出并将其替换为旧输入:
echo "ello" | cut -c2-
或者需要使用多个管道,这会太慢/效率低下。
更简单的解释
使用手动操作,这将替换我(用户)复制粘贴我作为示例给出的命令的输出(或我之前描述的伪代码),并将其用作同一命令的输入,重复相同的操作,直到剩余“一个”字节或字符。
答案1
如果我理解正确的话,您正在寻找这样的东西:
$ var=hello
$ while [ -n "$var" ]; do
printf -- "Var is now '%s'\n" "$var"
var=$(printf -- '%s\n' "$var" | cut -c2-);
done
Var is now 'hello'
Var is now 'ello'
Var is now 'llo'
Var is now 'lo'
Var is now 'o'
答案2
这确实有效在Linux上:
echo hello | tee /dev/fd/0
hello
hello
hello
...
echo hello | gawk '!length{exit(0)} {print; print substr($0,2) >"/dev/fd/3"; fflush()}' 3>/dev/fd/0
hello
ello
llo
lo
o
这利用了这样一个事实:在 Linux 上,所有管道实际上都是命名管道(即它们可以通过路径打开)。使用常规命名管道,它也可以在其他 Unix 系统上工作 - 请参阅此回答在 Stackoverflow 上。
答案3
你可以用递归来做到这一点:
command1() {
local var
IFS= read -r var
if [[ $var ]]; then
printf '%s\n' "$var"
cut -c2- <<< "$var" | "${FUNCNAME[0]}"
fi
}
然后:
$ echo hello | command1
hello
ello
llo
lo
o
答案4
这似乎有效:
foo() { [[ ! "${#1}" -eq 1 ]] && printf "%s" "$1" | cut -c2-; }
bar="hello"
while [[ ! -z $(foo "$bar") ]]; do bar=$(foo "$bar"); printf "%s\n" "$bar"; done
ello
llo
lo
o