for
Bash 루프의 출력을 정렬하려고 합니다 .
현재 루프에서 얻은 출력은 다음과 같습니다.
Directory: /some/long/directory/path Remote: some-remote
Directory: /some/dir/path Remote: other-remote
다음과 같이 정렬하려고 합니다.
Directory: /some/long/directory/path Remote: some-remote
Directory: /some/dir/path Remote: other-remote
이 출력을 생성하는 현재 기본 루프는 다음과 같습니다.
for dir in $(find /some/path -type d -name .git); do
cd $dir
remote=$(git remote)
printf "Directory: $dir\tRemote: $remote\n
done
나는 다음을 사용해 보았습니다.
column
(for 루프이기 때문에 각 행의 형식을 개별적으로 지정합니다)printf
(printf "Directory: %s Remote: %s\n" "$dir" "$remote"
)awk
(echo "Directory: $dir Remote: $remote" | awk '{printf ("%s-20s %s-20s %s-20s %s-20s",$1 $2 $3 $4)}'
)
이 명령에는 다른 많은 변형이 있습니다.
아마도 기본적인 것이 빠졌을 것입니다(온라인에서 다른 예제를 보고 페이지를 읽으려고 최선을 다했지만 man
) 제대로 작동하지 않습니다.
누군가 내가 잘못하고 있는 점을 지적해 준다면 정말 감사하겠습니다.
답변1
column
잘 작동할 겁니다. 그러나 모든 루프 반복에 추가하지는 않지만 마지막에는 다음을 추가합니다.
for
...
done | column -t
산출:
Directory: /some/long/directory/path Remote: some-remote
Directory: /some/dir/path Remote: other-remote
스크립트에 대한 몇 가지 추가 참고 사항:
find
이와 같이 출력을 반복 하지 마십시오 .여기에서 확인하세요.- 참조 파일/디렉터리 변수 -->
cd "$dir"
printf
FORMAT
문자열에 변수를 사용 하지 마세요 . -->printf 'Directory: %s\tRemote: %s\n' "$dir" "$remote"
답변2
column
그러나 을 사용할 수 있습니다 .
- 먹이를 주어야 해포괄적인각 반복 대신 루프로 출력합니다.
- 너는 피해야 해반복의 출력
find
.
쉘이 임을 나타내었으므로 및 (그리고 @Kusalananda가 지적한 대로 ) 옵션을 사용하여 쉘에서 직접 반복 bash
할 수 있습니다 .globstar
nullglob
dotglob
shopt -s globstar
shopt -s nullglob
shopt -s dotglob
for d in **/.git/
do
cd "$d"
printf "Directory: %s\tRemote: %s\n" "${d%/.git/}" "$(git remote)"
cd - >/dev/null
done | column -t -s $'\t'
- 이
globstar
옵션을 사용하면**
모든 깊이의 중간 디렉터리와 일치하는 glob("와일드카드"라고도 함)을 활성화하여 루프 내에서 디렉터리 트리에 깊이 들어갈 수 있습니다. nullglob
일치하는 디렉터리가 없는 경우 이 옵션을 사용하면 전혀 반복하지 않습니다. 이것이 없으면 glob 패턴은 다음 내용이 포함된 디렉터리를 참조하는 것으로 처리됩니다.리터럴 이름**/.git/
일치하는 파일 이름이 없으면 루프는 이 (의미 없는) 값으로 한 번 실행됩니다$d
.- 이 옵션은 "숨겨진" 중간 디렉터리(예: 에서와 같이 a로 시작하는 디렉터리 )도 일치하는지
dotglob
확인합니다 .**
.
some/directory/.path/repository
- 경로의 - 부분이 필요하지 않으므로 쉘 문자열 처리 지침은
.git/
값에서${d%/.git/}
마지막으로 나타나는 을 제거 합니다./.git/
$d
- 루프 내의 출력은 탭으로 구분되므로
column
명령에-s $'\t'
기본값(예: 공백으로 구분된 열) 대신 탭을 입력 열 구분 기호로 사용하도록 지시합니다.
답변3
루프를 다시 작성하십시오.
find /some/path -type d -name .git -exec sh -c '
for dirpath do
printf "Directory: %s@Remote: %s\n" \
"${dirpath%/.git}" \
"$( git -C "$dirpath" remote )"
done' sh {} + |
column -s '@' -t
column
이는 형식화된 출력 에 사용됩니다 find
. 이 명령은 일괄적으로 발견된 디렉터리 경로로 호출되는 인라인 스크립트를 사용하여 find
모든 디렉터리를 찾고 필요한 정보를 출력합니다. 출력을 위해 인라인 스크립트는 지정된 디렉터리 경로를 다음으로 수정합니다..git
sh -c
아니요끝에 실제 콘텐츠를 포함합니다 /.git
. 즉, Git 프로젝트 디렉터리를 가리킵니다.
출력은 나중에 데이터를 정렬하는 데 사용되는 @
문자로 표로 작성됩니다 . column
다른 문자를 사용해야 하는 경우 @
인라인 sh -c
스크립트와 호출을 변경하세요.column
관련된:
Git 저장소가 있는 경우많은 종류의리모컨의 경우 각 리모컨의 출력을 개별적으로 복사해야 할 수도 있습니다.
find /some/path -type d -name .git -exec sh -c '
for dirpath do
git -C "$dirpath" remote |
while IFS= read -r remote; do
printf "Directory: %s@Remote: %s\n" \
"${dirpath%/.git}" "$remote"
done
done' sh {} + |
column -s '@' -t
여기서는 행을 읽습니다 git -C "$dirpath" remote
. 각 줄에는 Git 원격의 이름이 포함되며 각 원격 읽기에 대해 출력됩니다.
이것은 출력될 수 있습니다
Directory: /some/path/src Remote: origin
Directory: /some/path/src Remote: private
저장소에 /some/path/src
두 개의 리모컨이 있는 경우.
재미삼아 JSON 출력을 원합니다.
find /some/path -type d -name .git -exec sh -c '
for dirpath do
git -C "$dirpath" remote |
while IFS= read -r remote; do
jo directory="${dirpath%/.git}" remote="$remote"
done
done' sh {} +
가능한 출력:
{"directory":"/some/path/src","remote":"origin"}
{"directory":"/some/path/src","remote":"private"}
{"directory":"/some/path/yash-shell","remote":"origin"}
{"directory":"/some/path/zsh-shell","remote":"origin"}
{"directory":"/some/path/datamash","remote":"origin"}