别名管道输入 awk

别名管道输入 awk

我正在尝试创建一个ll带有awk管道别名。我试图使用以下内容来转义撇号答案

alias lh= `ll -h | awk {'print  $9, \"-\" ,$5, \"-\", $8, \"-\",$7, $6'}` 

但它似乎不起作用。

bash和的控制台输出结果zsh是相同的。


awk: cmd. line:1: {print  $9, \"-\" ,$5, \"-\", $8, \"-\",$7, $6}
awk: cmd. line:1:             ^ backslash not last character on line
awk: cmd. line:1: {print  $9, \"-\" ,$5, \"-\", $8, \"-\",$7, $6}
awk: cmd. line:1:             ^ syntax error

进入时

alias lh= `ll -h | awk {'print  $9, "-" ,$5, "-", $8, "-",$7, $6'}`

输出意味着空。

答案1

您的别名定义存在几个语法问题。然而,第一个问题是解析输出ls 强烈劝阻因为涉及它的代码最终会偶然发现带有“非平凡”字符(例如空格、制表符和换行符)的文件。此外,特别是时间戳的输出格式可能会根据文件实际的“旧”程度而变化,这意味着您可以在输入中包含更多或更少的空格分隔“字段”,具体awk取决于实际文件,或者一个字段的含义发生变化(例如,从“旧文件”的年份到“最近的文件”的一天中的时间)。这两个方面就是@steeldriver所说的别名“脆弱”。

“明显”的问题是:

  1. 后面有一个空格=。这实际上会使别名lh未定义(至少在bash)。
  2. 您将别名定义括在反引号 ( `) 中,可能是为了创建“第三层”引用。但是,反引号是命令替换的语法(尽管现在已弃用),即lh包含ll | awk ...管道的控制台输出并尝试执行作为命令。
  3. ll您依赖于存在或至少预定义为 的别名的命令ls -l。情况可能是这样,也可能不是。
  4. 您的awk程序启动时单引号和大括号的顺序错误。正确的语法是awk ' { ... } '.

请注意,如果这是 shell 脚本的一部分,您可能需要通过以下方式运行它shellcheck,也可在许多 Linux 发行版上作为独立工具使用,以捕获许多与语法相关的错误。

您遇到的问题的直接解决方案确实是正确的引用和转义。你可以尝试类似的东西

alias lh="ls -lh | awk '{print  \$9, \"-\" ,\$5, \"-\", \$8, \"-\",\$7, \$6}'"

其中别名是 中的所有内容" ... ", 的输入awk明确声明为ls -lhawk程序用单引号括起来,并且程序内的字段引用awk受到保护,以免在“别名的定义时”过早解释为 shell 位置参数反斜杠转义(因此awk实际上将它们视为$9而不是被 shell 实例的第 9 个位置参数替换,该参数可能为空)。

然而

  • 中找到的建议您链接的问题的答案之一- 定义一个函数 - 是摆脱“引用地狱”的更好方法(正如@ilkkachu提到的),所以像

    lh() { ls -lh | awk '{print  $9, "-" ,$5, "-", $8, "-",$7, $6}'; }
    

    更清晰、更容易理解

  • 我建议ls完全避免解析,并建议使用以下find基于别名:

    lh() { find . -maxdepth 1 -type f ! -name ".*" -printf "%f - %s - %TY - %Td %Tb\n"; }
    

    它使用 的printf格式化选项来find可靠地输出所需的文件属性。唯一的缺点是没有-h人类可读的尺寸选项。

    ! -name ".*"过滤器用于模拟ls忽略隐藏文件的标准行为。如果您希望列出它们,则可以省略该部分。

相关内容