我不记得如何将命令附加到 shell 脚本。我搜索了附加,添加,连接,还有更多没有成功。
基本上我有
belly = tail -n +"$HEAD" "$1" | head -n $((TAIL-HEAD+1))
if [ -z "${NUMBER+x}" ]; then # check if NUMBER exists
tail -n +"$HEAD" "$1" | head -n $((TAIL-HEAD+1))
else
tail -n +"$HEAD" "$1" | head -n $((TAIL-HEAD+1)) | cat -n
fi
它工作得很好,但我不喜欢重复的逻辑。我知道我可以使用函数或 eval,但是有没有更简单的方法来做到这一点?在我的脑海里有这样的东西:
belly = tail -n +$HEAD $1 | head -n $((TAIL-HEAD+1))
if [ -z "${NUMBER+x}" ]; then # check if NUMBER exists
belly
else
belly | cat -n
fi
但这不起作用。我缺少什么?
答案1
其实这个问题可能已经在这里得到了回答:条件管道
该答案采用 shellif/then/else
机制并使用它来嵌入逻辑里面管道。您也可以使用运算符来完成此&&
操作,但读起来不太干净,所以我更喜欢if
.
基本上在你的情况下,该tail
行将像这样(另请注意-z
to的更改-n
):
tail -n +"$HEAD" "$1" |
head -n $((TAIL-HEAD+1)) |
if [ -n "${NUMBER+x}" ]; then cat -n; else cat; fi
(这可能有一些错误,我不太热衷于 Linux shell 编程。但你明白了。)
答案2
一种选择是设置一个变量来管理管道的变化部分。如果唯一改变的部分是命令行参数,则实现很简单:
cat_arg=""
if [ -n "${NUMBER+x}" ]; then
cat_arg="-n"
fi
somepipeline ... | cat $cat_arg
虽然这样,很难完全移除管道的最后一部分,所以我们会无用地使用猫,但这可能并不重要。另外,这取决于不是引用变量,这使得无法在更改的参数中使用空格或全局字符。
所以数组会更好:
final=(cat)
if [ -n "${NUMBER+x}" ]; then
final=(cat -n)
fi
somepipeline ... | "${final[@]}"
或者您可以创建两个函数并通过变量调用其中一个。
顺便说一句,shell 函数也是您其他问题的答案。
# define the function
belly() {
tail -n +"$HEAD" "$1" | head -n $((TAIL-HEAD+1))
}
if ... ; then
belly "$1" | this
else
belly "$1" | that
fi
您需要$1
显式传递,因为函数有自己的位置参数上下文。
答案3
本质上,您想要完成的是根据状态传递或不传递-n
选项cat
$NUMBER
只需这样做:
tail -n +"$HEAD" "$1" | head -n $((TAIL-HEAD+1)) | cat ${NUMBER:+'-n'}
我们也可以取消 UUOC 场景:
eval "tail -n +\"$HEAD\" \"\$1\" | head -n \$((TAIL-HEAD+1)) ${NUMBER:+|cat -n}"