使用 head 和 cut 的别名管道

使用 head 和 cut 的别名管道

我想创建一个别名来快速查看带有逗号分隔符的表格式文件:

alias thead='head | cut -d, -f1- | column -s, -t'

后来这样使用

thead file.csv

然而,这不起作用。正确的语法是什么?

答案1

对于比简单命令更高级的任何内容,请使用 shell 函数而不是别名:

thead () {
    head -- "$1" | cut -d, -f1- | column -s, -t
}

这个 shell 函数将head在其第一个参数上运行,然后通过管道发送结果(尽管由于cutgets全部由于 的列-f 1-,这部分可能会被删除;我把它留在这里,就像你在原来的管道中一样)。

或者,

thead () {
    head -- "$2" | cut -d "$1" -f1- | column -s "$1" -t
}

...能够将其用作

thead ',' filename

或者甚至,允许选修的分隔符(如果没有给出则使用逗号),

thead () {
    local delim=','

    if [ "$#" -gt 1 ]; then
        delim=$1
        shift
    fi
    
    head -- "$1" | cut -d "$delim" -f1- | column -s "$delim" -t
}

上面的函数定义可以放在您通常定义别名的任何地方。


在别名中使用管道的问题是,当您将别名与参数一起使用时,该参数将添加到管道的末尾,而不是添加到管道中的第一个命令之后。


手册bash包含这句话

对于几乎所有用途,别名都被 shell 函数取代。

答案2

alias扩展只是文本替换,由 shell 再次解析,因此当您这样做时:

thead file.csv

刚刚替换为:

head | cut -d, -f1- | column -s, -t file.csv

并再次解释。

如果你写的是:

<file.csv thead

或者

cat file.csv | thead

或者

{ thead; } < file.csv

它会起作用,因为它会被替换为:

<file.csv head | cut -d, -f1- | column -s, -t
cat file.csv | head | cut -d, -f1- | column -s, -t
{ head | cut -d, -f1- | column -s, -t; } < file.csv

分别。无论如何,正如 @Kusalananda 所说,使用函数或脚本比使用别名要好得多。在这里,我只想这样做:

thead() { head "$@" | cut -d, -f1- | column -s, -t; }

所以你可以thead -n 12 file.csv file2.csv这样做。

相关内容