pipe multiple commands to less
If you want to move with :n
and :p
there is no other way but to run the commands, output the outputs to files, then less
them:
svndiff ()
{
d=$(mktemp -d /tmp/svndiffsXXXXX)
for a in $(svn status | \grep ^M | sed 's/M //');
do
svn diff "$a" > $(mktemp $d/diffXXXXX) 2>&1;
done
less "$d"/diff*
rm -fr "$d"
}
(If you need them in order let me know and we can apply numbering.)
Otherwise, you could call a shell executing all of your commands, then pipe the concatenated output to less
.
You could use process substitution:
less -f <(svn diff this) <(svn diff that)
But that's hard to use in a loop. Probably best to just use temporary files:
#!/bin/bash
dir=$(mktemp -d)
outfiles=()
IFS=$'\n'
set -f
for file in $(svn status | \grep ^M | sed 's/M //') ; do
outfile=${file#.} # remove leading dot (if any)
outfile=${outfile//\//__} # replace slashes (if any) with __
svn diff "$file" > "$dir/$outfile";
outfiles+=("$dir/$outfile") # collect the filenames to an array
done
less "${outfiles[@]}"
rm -r "$dir"
The above tries to keep the filenames visible in the names of the temp files, with some cleanup for slashes and leading dots. (In case you get paths like ./foo/bar
. I can't remember how svn
outputs the file names, but anyway...)
The array is there to keep the order, though as @Kusalananda said, we could just do "$dir"/*
instead, if the order doesn't matter. set -f
and IFS=$'\n'
in case someone creates file names with glob characters or white space.
Of course we could simplify the script a bit and create, say numbered temp files instead.
Using GNU Parallel you could do something like:
files=$(svn status | \grep ^M | sed 's/M //' |
parallel --files svn diff {})
less $files
rm $files