printf
한 번의 호출로 두 개의 별도 열에 인쇄 하려는 두 개의 배열이 있습니다 . 다음과 같은:
printf "%-${padding}s→ %s\n" "${lnFrom[@]}" "${lnTo[@]}"
산출:
dotfiles/git/gitconfig → dotfiles/hyper/hyper.css
dotfiles/hyper/hyper.js → dotfiles/nvim/nvimrc
dotfiles/nvim/warm_nature.vim → dotfiles/zsh/zshrc
~/.gitconfig → ~/.hyper.css
~/.hyper.js → ~/.nvimrc
~/.vim/colors/warm_nature.vim → ~/.zshrc
처음 세 행은 배열을 나타내고 lnFrom
마지막 세 행은 lnTo
해당 열에 있어야 합니다.
( padding
printf 문은 배열에서 가장 긴 문자열의 길이를 포함하는 변수일 뿐입니다 lnFrom
.)
단일 printf 호출을 유지하면서 이 문제를 해결하는 방법에 대한 아이디어가 있습니까? (루프를 도입하지 않고)
답변1
형식 지정자가 각 배열에 있는 요소 수와 일치하지 않습니다. 배열 확장이 발생하면 여러 단어가 생성되며 각 단어에는 %s
일치하는 지정자가 필요합니다. 따라서 printf
첫 번째 배열의 모든 요소로 채운 다음 두 번째 배열의 모든 요소로 채웁니다.
결합된 두 배열에서 인쇄할 요소의 정확한 수를 알지 못하면 정적 형식 지정자 문자열을 하드코딩할 수 없습니다. 한 가지 접근 방식은 두 배열이 모두 확장될 때 생성될 총 요소 수를 추적하여 형식 지정자 배열을 동적으로 생성하는 것입니다.
count=$(( ${#lnFrom[@]} + ${#lnTo[@]} ))
이제 배열을 만듭니다.
format_specifiers=( "%-${padding}s" )
for ((i=1; i<=count-1; i++)); do
[ "$i" -eq "${#lnFrom[@]}" ] && { format_specifiers+=( " %s" ); continue; }
format_specifiers+=( "→ %s" )
done
이제 요소를 다음과 같이 인쇄하십시오.
printf "${format_specifiers[*]}" "${lnFrom[@]}" "${lnTo[@]}"
위 내용을 테스트한 경우 ->
첫 번째 배열이 끝나는 부분과 다음 배열이 시작되는 부분 사이에 추가 항목이 포함될 수 있습니다. 이는 형식 지정자 배열을 생성할 때 배열의 시작/끝 위치를 결정하지 않았기 때문입니다.
당신은 이것을 할 수 있습니다
for ((i=1; i<=count-1; i++)); do
[ "$i" -eq "${#lnFrom[@]}" ] && { format_specifiers+=( " %s" ); continue; };
format_specifiers+=( "→ %s" )
done