通过 xargs realpath 进行管道传输时如何过滤不存在​​的文件?

How can I filter nonexistent files when piping through xargs realpath?

我已经养成了使用以下命令在我的编辑器中快速打开相关文件进行代码审查的习惯。

git diff --name-only master... | xargs realpath | someEditor

但最近遇到一个问题,第一个或第二个文件可能被删除了,编辑器会报错,其余文件打不开,逼着我一个一个打开。

是否有类似的命令可以跳过不存在的文件?

狭义地解决问题:使用 Readlink

由于您使用的是 Ubuntu(具有 GNU 阅读链接),您可以使用 readlink -e,它具有您 希望 的确切行为realpath 将提供:

git diff --name-only master... \
  | xargs -d $'\n' readlink -e -- \
  | xargs -d $'\n' someEditor

由于您使用的是 Ubuntu,它提供 GNU xargs,由于在 [=18] 上使用 -d $'\n',此代码将正确处理带有空格、文字引号或文字反斜杠的文件名=] 调用。


狭义地解决问题:使用 Realpath

如果我们想坚持使用您现有的工具(也就是说,realpath 而不是 readlink)并且只添加一个存在性测试,它可能看起来像:

git diff --name-only master... \
  | xargs -d $'\n' sh -c 'for f; do [ -e "$f" ] && realpath "$f"; done' _ \
  | xargs -d $'\n' someEditor

实施建议

顺便说一句——考虑将您想要的实现封装在 ~/.bashrc 的 shell 函数中。这可能类似于...

forEachChangedFile {
  local -a files
  readarray -t files < <(
    git diff --name-only "${branchExpr:-master...}" \
      | xargs -d $'\n' readlink -e --
  )
  if (( $# )); then
    "$@" "${files[@]}"
  else
    "${EDITOR:-someEditor}" "${files[@]}"
  fi
}

...以后用作:

forEachChangedClient vim

branchExpr=someBranch..someOtherBranch forEachChangedFile emacs-client

不使用 xargs 编辑器的最终调用的优点是它使编辑器的标准输入保持清晰,因此您可以将它用于通过该渠道与用户通信的编辑器。