【问题标题】:Properly quote bash alias definition正确引用 bash 别名定义
【发布时间】:2019-04-23 05:44:07
【问题描述】:

我尝试将以下命令放入 bash 别名中。该命令本身可以正常工作,但是当我尝试为其设置别名时,出现以下错误:

命令

find . -maxdepth 1 -mindepth 1 -type d -exec sh -c 'echo "$(find "{}" -type f | wc -l)" {}' \; | sort -nr

别名

alias csfiles='find . -maxdepth 1 -mindepth 1 -type d -exec sh -c 'echo "$(find "{}" -type f | wc -l)" {}' \; | sort -nr'

错误:

-sh: alias 0: not found
-sh: alias {} \; | sort nr: not found

我认为这意味着我没有正确使用引号,但我无法确定正确的组合。帮忙?

【问题讨论】:

  • 我已经有一段时间没有使用别名了,但我认为您的别名太复杂了。我相信别名只是用来缩短一个带有参数的命令,即alias l='ls -al'。您可能需要创建一个函数csfiles。但是已经有一段时间了,所以我可能弄错了。
  • 我第二次创建一个 bash 函数来执行此操作。你可以用同样的方式调用它,如果需要的话可以传递参数。
  • 如前所述,find 命令对于某些文件名(例如包含双引号的文件名)将失败。不要尝试在命令中嵌入{};仅将其用作sh 的参数。 sh -c '....' _ {}。无论您在哪里使用{},请使用$1
  • @chepner 这是一个非常好的观点!

标签: bash alias


【解决方案1】:

你的外部find 不会做任何你不能用简单的 glob 做的事情。这消除了一层引号(以及找到的每个目录的sh 进程)。

# Ignoring the issue of assuming no file name contains a newline
for d in ./*/; do
   echo "$(find "$d" -type f | wc -l) $d"
done

只需定义一个 shell 函数来消除对alias 的参数施加的第二层。

csfiles () {
  for d in ./*/; do
    echo "$(find "$d" -type f | wc -l) $d"
  done
}

find 的剩余调用也可以替换为for 循环,消除每个文件名一行的问题假设:

csfiles () {
  for d in ./*/; do
    echo "$(for f in "$d"/*; do [ -f "$f" ] && echo; done | wc -l) $d"
  done
}

如果 find 支持 -printf 主文件,您可以保留它,因为您不关心文件的实际名称,只关心每个文件只有一行输出。

csfiles () {
  for d in ./*/; do
    echo "$(find "$d" -type f -printf . | wc -l) $d"
  done
}

【讨论】:

    【解决方案2】:

    您可以在定义周围使用双引号,如下所示:

    alias foo="find . -maxdepth 1 -mindepth 1 -type d -exec sh -c 'echo \"\$(find \"{}\" -type f | wc -l)\" {}' \; | sort -nr"
    

    定义中的每个文字 " 都会被转义:\"

    注意:您还需要转义内部命令替换,以防止它在别名定义时被扩展。赞这个... \$(...)


    作为对 chepners 评论的跟进,您应该将文件名作为参数传递给内部 find 命令。否则,如果您的某个文件夹的名称中包含 ",您将遇到问题:

    alias foo="find . -maxdepth 1 -mindepth 1 -type d -exec bash -c 'echo \"\$(find \"\${1}\" -type f | wc -l) \"\${1}\" \"' -- \"{}\" \; | sort -nr"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-27
      • 1970-01-01
      • 2018-09-14
      • 1970-01-01
      相关资源
      最近更新 更多