printf는 열이 아닌 줄을 인쇄합니다.

printf는 열이 아닌 줄을 인쇄합니다.

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해당 열에 있어야 합니다.

( paddingprintf 문은 배열에서 가장 긴 문자열의 길이를 포함하는 변수일 뿐입니다 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

관련 정보