各行でコマンドを実行したときに出力をリダイレクトするループファイル

各行でコマンドを実行したときに出力をリダイレクトするループファイル

私はLinuxでbashを学んでいます。 「ファイルから読みながらループ」のスクリプトを見つけて、以下のように修正しました。すべての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=read-r-line」を理解する影響の微妙さに関する情報に関連する問題をリンクしますread

cdと一緒にサブシェルを使用するgit statusことは、ディレクトリを変更してもループの後続の反復やwhile

答え2

私はそれをグーグルし、これが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あなたが何かをしたいなら、それはうまくいくかもしれませんみんなファイルのメタデータで明確に表示される特定の条件に一致する特定のサブツリーのファイル/ディレクトリ。ただし、既存のリストがある場合、これを処理する最善の方法はシェルループです。

答え3

あなたの質問は単純なタイプミスです。スティーブンすでに。

git statusファイルの行で指定された各ディレクトリでタスクを実行するには、次のようにすることもxargsできます。

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

これgit -C {} statusにはファイルのすべての行が必要ですrepo.list{}ファイルから読み取られた行に置き換えられ、オプションを使用すると、ユーティリティは現在のディレクトリではなくサブコマンドの代替ディレクトリを使用します-Cgitstatus

各呼び出しの前にストレージパスを出力するには、次のスクリプトを呼び出し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"

関連情報