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

ただし、これにより次のような出力が発生します。ここでは、2つの連続したスペース(Unicodeコードポイント32)が保存されていることがわかります。

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

(私も使ってxargsみましたtr

必要な出力はURLのリストです。たとえば、次のようになります。

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

私がここで何を見逃しているのでしょうか?

答え1

2つのスペースではなくタブです。

シェルループを使用して、現在の作業ディレクトリにディレクトリがあるサブディレクトリを繰り返し、空白で区切られた最初のフィールドを.git繰り返し(最後に追加されたタグを削除するために)各リモート+ URLに渡すことができます。 1行だけ表示するには:cut(fetch)(push)gituniq

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

最後の項目は、cut -f 2タブで区切られた2番目のフィールドを返してURLを区切ります。

タブとスペースが同じように処理されることを考慮するとawk(特定の区切り記号やパターンを使用しない限り)、後続のパイプを単一の呼び出しに置き換えることができますawk

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

答え2

bashtrbashに付属のすべての空白cutxargsトークン化、およびglobの問題を処理する代わりに、作業に適した言語を使用し、gitリポジトリと対話するためのライブラリモジュールを含めることができます。たとえば、Perl は次のように提供されます。Git::生基準寸法。

これは非常に単純な一行の例です。 (Git::Rawそれよりもはるかに多くのことをすることは注目に値し、モジュールを使用するスタンドアロンPerlスクリプトを書く方が良いでしょう。)

読みやすくするために改行とインデントを追加しました。現状のまま動作するか、すべて1行に圧縮されて動作します。

$ 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

注:Perlには含まれておらず、配布パッケージと一緒に、または配布パッケージを介してインストールする必要がありますGit::Raw(たとえば、Debianなど。他の配布にも存在する可能性があります)。このモジュールはPerlラッパーです。cpanapt-get install libgit-raw-perllibgit2したがって、CPANを使用して手動でインストールするには、gcclibgit2開発ライブラリとヘッダーをインストールする必要があります。

また、注目すべき点は、Perl(または他のほとんどすべての言語)を使用せずにGit::Raw出力を解析するのがgitbashよりも簡単で、エラーの可能性が低いことです。 Perlは文字列のマッチングと操作のために特別に設計されているので、BashでやろうとしていることはPerlではマイナーなことです。


さて、気に入ったらpython確認してみるのもいいようです。GitPython代わりに。 Debian などでは を使ってインストールできapt-get install python3-git、他のディストリビューション用にパッケージ化されている場合もあります。これは使用されておらず、bashで実行したいものと同様のlibgit2コマンドの周りのラッパーです。git

昨日はなんだか見逃したんですが、libgit2ウェブサイトではこう言いました。 フィジット2Git::RawPerlと同様に、Pythonでも同じことを行います(つまり、C libgit2ライブラリを使用するので、必要に応じて分岐するよりも高速で、git出力解析の問題のリスクを防ぎます)。 Debian パッケージは でありpython3-pygit2、他のディストリビューション用にもパッケージ化できます。

関連情報