循环文件以对每一行运行命令时的输出重定向

循环文件以对每一行运行命令时的输出重定向

我正在Linux上学习bash,我找到了“while循环从文件中读取”的脚本并进行了如下修改,我正在尝试读取包含所有git存储库的列表文件,并且我想迭代所有这些git存储库并运行git status所有这些:

while read line; 
    do  echo $line;
        cd $line;
        git status;
done < repo.list

这部分工作正常,我可以在标准输出中看到每个存储库的状态,但是当我尝试将输出写入另一个文件时,它不起作用:

while read line; 
    do  echo $line;
        cd $line;
        git status;
done < repo.list
> status.txt

我如何整合所有git status输出并写入文件?谢谢!

答案1

当重定向到新行时,它适用于空命令;要解决此问题,请将其放在线上done

while IFS= read -r line; 
    do  echo "$line"
        (cd "$line"; git status)
done < repo.list > status.txt

也可以看看了解 IFS理解“IFS=读取-r行”以及有关影响微妙之处的信息的链接问题read

cd一起使用和的子 shellgit status意味着更改目录不会影响循环的后续迭代,甚至不会影响运行while.

答案2

我用谷歌搜索了一下,发现这个 find mydir -name .git -type d

你可以做这样的事情,也许:

find . -name '.git' -type d -print -execdir git status \;

这将查找名为 的目录.git,然后对于每个目录,打印其路径,然后转到包含的目录并git status在那里运行。 (find -exec将在原始目录中运行命令,-execdir转到匹配的文件/目录所在的位置。)

你会得到像这样的输出

./this-stuff/.git
On branch master
Your branch is up to date with 'origin/master'.

并且需要更多的技巧来对其进行后处理.git。 (例如,-exec sh -c 'echo "${1%.git}"' sh {} \;代替-print。)

一般来说,find如果您想做某事,可能会起作用全部某些子树中的文件/目录,匹配从文件的元数据中显而易见的某些条件。但是,如果您有一个现有列表,则 shell 循环是处理它的最佳方法。

答案3

您的问题是一个简单的打字错误,正如斯蒂芬已经。

git status在文件中的行给出的每个目录中运行的任务xargs也可以使用以下命令完成:

xargs -I {} git -C {} status <repo.list >status.txt

git -C {} status需要文件中的每一行repo.list。将会{}被从文件中读取的行替换,并且选项-C将使git实用程序使用status子命令的替代目录来代替当前目录。

要在每次调用之前输出存储库路径git status,请调用sh -c脚本:

xargs -I {} sh -c 'printf "REPOSITORY: %s\n" "$1"; git -C "$1" status' sh {} <repo.list >status.txt

在脚本内部sh -c,存储库路径名由 给出"$1"

相关内容