代码之家  ›  专栏  ›  技术社区  ›  zeeple

正确引用bash别名定义

  •  1
  • zeeple  · 技术社区  · 6 年前

    我有以下命令,我正试图将其放入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
    

    我认为这意味着我没有正确使用引号,但是我在确定正确的组合时遇到了困难。帮助?

    2 回复  |  直到 6 年前
        1
  •  4
  •   chepner    6 年前

    你外部 find 用一个简单的地球仪做不到的事情。这消除了一层引号(以及 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
    }
    

    剩余呼叫 找到 也可以替换为 for 循环,消除每个文件名一行的问题假设:

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

    你可以保持 找到 如果它支持 -printf 主文件,因为您不关心文件的实际名称,只需要为每个文件获得一行输出即可。

    csfiles () {
      for d in ./*/; do
        echo "$(find "$d" -type f -printf . | wc -l) $d"
      done
    }
    
        2
  •  1
  •   hek2mgl    6 年前

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

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

    每一文字 " 在定义内部转义: \" .

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


    作为对chepners注释的后续操作,您应该将文件名作为参数传递给inner find命令。否则,如果其中一个文件夹的名称带有 其中:

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