Instead of messing around with bash and tr and cut and xargs and all the whitespace and word-splitting and glob issues that bash brings, you could use a language more suited to the job...and one that includes a library module for interacting with git repos. For example, perl with the Git::Raw module.
Here's a very simple one-liner example (although it's worth noting that Git::Raw is capable of much more than this and you'd probably be better off writing a stand-alone perl script that uses the module):
I've added newlines and indentation for readability. It works as-is, or all squished up on one line.
$ 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
In English, that's:
- Open each repo listed on the command line, ignoring directories that aren't actually git repos,
- iterate over the repo's remotes and print their URLs.
Sample output. I ran the one-liner above in a directory that I sometimes use to clone various repos from github. I wrote the one-liner to print the directory name before the list of remotes belonging to that repo, and a blank line after each directory processed.
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
Note: Git::Raw is not included with perl, it needs to be installed with cpan or via a distro package (e.g. on Debian etc, apt-get install libgit-raw-perl. Other distros probably have it too). The module is a perl wrapper around libgit2 so installing it manually with CPAN will require gcc and the libgit2 development library & headers installed.
Also worth noting: even without Git::Raw parsing the output of git with perl (or almost any other language) is going to be a lot easier and a lot less error-prone than doing it in bash. Perl in particular is designed for string matching and manipulation, so doing what you're trying to do in bash is trivial in perl.
BTW, if you prefer python, you may want to look at GitPython instead. On Debian etc, you can install it with apt-get install python3-git, and it's probably packaged for other distros too. This one doesn't use libgit2, it's a wrapper around the git command, similar to what you're trying to do in bash.
I somehow missed this yesterday, but the libgit2 web site says that pygit2 does for python what Git::Raw does for perl (i.e. it uses the C libgit2 library - so will be faster than forking git whenever needed, and avoids the risk of output-parsing problems). Debian package is python3-pygit2, and it's probably packaged for other distros too.
lsintoxargsis very dangerous, and the output oflsshouldn't be used for anything except displaying file/directory listings for a human to read. See Why not parsels(and what to do instead)? – cas Aug 22 '23 at 12:09