我能怎么做
{$several_commands} | less
并将less
其视为多个文件并使用:n
和启用导航:p
。
这可能不是更清楚的解释,所以让我们考虑一个例子。我目前有一个功能
svndiff ()
{
for a in `svn status | \grep ^M | sed 's/M //'`;
do
svn diff $a | less;
done
}
目的显然是为了查看less
我修改的所有文件的差异。但使用这种语法,我必须使用 keyQ
关闭一个“文件”并打开下一个“文件”。我希望能够使用less
命令:n
(下一个文件)和:p
(上一个文件)在文件之间导航。我怎样才能做到这一点 ?
答案1
您可以使用进程替换:
less -f <(svn diff this) <(svn diff that)
但这很难在循环中使用。可能最好只使用临时文件:
#!/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"
上面的代码尝试保持文件名在临时文件的名称中可见,并对斜杠和前导点进行了一些清理。 (如果你得到像这样的路径./foo/bar
。我不记得如何svn
输出文件名,但无论如何......)
数组是为了保持顺序,尽管正如 @Kusalananda 所说,"$dir"/*
如果顺序无关紧要,我们可以这样做。set -f
如果IFS=$'\n'
有人创建带有全局字符或空格的文件名。
当然,我们可以稍微简化脚本并创建编号的临时文件。
答案2
如果您想移动:n
并且:p
没有其他方法只能运行命令,将输出输出到文件,然后less
:
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"
}
(如果您需要它们,请告诉我,我们可以应用编号。)
否则,您可以调用执行所有命令的 shell,然后将连接的输出通过管道传输到less
.
答案3
使用 GNU Parallel 你可以做类似的事情:
files=$(svn status | \grep ^M | sed 's/M //' |
parallel --files svn diff {})
less $files
rm $files