如何将 tr 与 xargs 结合并剪切以挤压重复

如何将 tr 与 xargs 结合并剪切以挤压重复

最高答案这个问题演示了cut可以与 with 一起使用来tr根据重复空格进行剪切

< file tr -s ' ' | cut -d ' ' -f 8

我想要获取目录中多个 Git 存储库的远程地址,并尝试使用以下内容从每个存储库中提取远程 URL 字段:

ls | xargs -I{} git -C {} remote -vv | sed -n 'p;n' | tr -s " " | cut -d ' ' -f1

但是,这会导致(例如)以下输出,其中我可以看到保留了两个连续的空格(Unicode 代码点 32):

origin  https://github.com/jik876/hifi-gan.git
origin  https://github.com/NVIDIA/NeMo.git
origin  https://github.com/NVIDIA/tacotron2.git

(我也使用xargstr

所需的输出是 URL 列表,例如:

https://github.com/jik876/hifi-gan.git
https://github.com/NVIDIA/NeMo.git
https://github.com/NVIDIA/tacotron2.git

我在这里缺少什么?

答案1

那是一个制表符,而不是两个空格。

您可以使用 shell 循环迭代当前工作目录中具有目录的子目录.git,然后迭代cut第一个空格分隔的字段(以删除末尾添加的(fetch)和标签),然后将其传递到每个远程+URL 只显示一行:(push)gituniq

for r in ./*/.git/; do
    git -C "$r" remote -v
done | cut -f 1 -d ' ' | uniq | cut -f 2

最后一个cut -f 2通过返回第二个制表符分隔字段来隔离 URL。

考虑到awk制表符和空格的处理方式相同(除非您使用特定的分隔符或模式),我们可以通过一次调用来替换尾随管道awk

for r in ./*/.git/; do
    git -C "$r" remote -v
done | awk '!seen[$2]++ { print $2 }'

答案2

bash您可以使用一种更适合这项工作的语言......并且包含用于与 git 存储库交互的库模块,而不是搞乱bash 带来的tr所有空格cutxargs分词和 glob 问题。例如,perl 带有Git::原始模块。

这是一个非常简单的单行示例(尽管值得注意的是,它的Git::Raw功能远不止于此,并且您最好编写一个使用该模块的独立 Perl 脚本):

为了便于阅读,我添加了换行符和缩进。它按原样工作,或者全部压缩在一行上。

$ perl -MGit::Raw -l -e '
  foreach my $d (@ARGV) {
    $d =~ s/\.git$//;
    next unless -d "$d/.git";
    my $repo = Git::Raw::Repository->open($d);

    print $d;
    foreach my $r ($repo->remotes()) {
     print $r->url
    };
    print "";
  }' */.git

用英语来说,那就是:

  1. 打开命令行上列出的每个存储库,忽略实际上不是 git 存储库的目录,
  2. 迭代存储库的遥控器并打印它们的 URL。

示例输出。我在一个我有时用来从 github 克隆各种存储库的目录中运行了上面的一行代码。我编写了一行代码,在属于该存储库的远程列表之前打印目录名称,并在处理的每个目录之后打印一个空白行。

mgetty
https://github.com/Distrotech/mgetty.git

roxterm
https://github.com/realh/roxterm.git

zpool-iostat-viz
https://github.com/chadmiller/zpool-iostat-viz.git

注意:Git::Raw不包含在 perl 中,它需要与发行版包一起安装cpan或通过发行版包安装(例如在 Debian 等上apt-get install libgit-raw-perl。其他发行版可能也有它)。该模块是一个 perl 包装器libgit2因此,使用 CPAN 手动安装需要gcc安装 libgit2 开发库和标头。

另外值得注意的是:即使不使用 perl(或几乎任何其他语言)Git::Raw解析输出,git也会比在 bash 中更容易且更不容易出错。 Perl 特别是为字符串匹配和操作而设计的,因此在 bash 中尝试做的事情在 Perl 中是微不足道的。


顺便说一句,如果您愿意python,您可能想看看GitPython反而。在 Debian 等上,您可以使用 来安装它apt-get install python3-git,并且它可能也为其他发行版打包。这个不使用libgit2,它是命令的包装器git,类似于您在 bash 中尝试执行的操作。

我昨天不知何故错过了这个,但libgit2网站上说 pygit2对 python 的作用Git::Raw与对 perl 的作用相同(即它使用 C libgit2 库 - 因此在需要时比 fork 更快git,并且避免了输出解析问题的风险)。 Debian 软件包是python3-pygit2,并且它可能也为其他发行版打包。

相关内容