Bash 쉘 스크립트 출력 정렬

Bash 쉘 스크립트 출력 정렬

내 스크립트:

date
echo -e "${YELLOW}Network check${NC}\n\n"

while read hostname
do

ping -c 1 "$hostname" > /dev/null 2>&1 &&

echo -e "Network $hostname : ${GREEN}Online${NC}" ||
echo -e "${GRAY}Network $hostname${NC} : ${RED}Offline${NC}"

done < list.txt
        sleep 30
clear
done

다음 정보가 출력됩니다.

Network 10.x.xx.xxx : Online   
Network 10.x.xx.xxx : Offline   
Network 10.x.xx.xxx : Offline   
Network 10.x.xx.xxx : Offline   
Network 10.x.xx.x : Online   
Network 139.xxx.x.x : Online   
Network 208.xx.xxx.xxx : Online   
Network 193.xxx.xxx.x : Online

다음과 같이 정리하고 싶습니다.

Network 10.x.xx.xxx       : Online  
Network 10.x.xx.xxx       : Offline   
Network 10.x.xx.xxx       : Offline    
Network 10.x.xx.x         : Online    
Network 139.xxx.x.x       : Online  
Network 208.xx.xxx.xxx    : Online    
Network 193.xxx.xxx.x     : Online  
Network 193.xxx.xxx.xxx   : Offline

답변1

형식화된 출력 의 경우 printf(또한생각보다 휴대성이 좋다echo). 또한 확장이 필요한 형식으로 저장하기보다는 색상 이스케이프 시퀀스의 실제 값을 저장하겠습니다 echo.

RED=$(tput setaf 1) GREEN=$(tput setaf 2) YELLOW=$(tput setaf 3)
NC=$(tput sgr0) 
online="${GREEN}online$NC" offline="${RED}offline$NC"

ping -c 1 "$hostname" > /dev/null 2>&1 && state=$online || state=$offline
printf 'Network %-15s: %s\n' "$hostname" "$state"

%-15szsh길이( 및 의 문자 수로 fish측정) 가 되도록 문자열의 오른쪽에 공백을 채우는 형식 사양입니다.대부분의 다른 쉘/printf의 바이트)은 15 이상입니다.

$ printf '|%-4s|\n' a ab abc abcd abcde
|a   |
|ab  |
|abc |
|abcd|
|abcde|
 printf '|%4s|\n' a ab abc abcd abcde
|   a|
|  ab|
| abc|
|abcd|
|abcde|

자르기:

$ printf '|%.4s|\n' a ab abc abcd abcde
|a|
|ab|
|abc|
|abcd|
|abcd|
$ printf '|%4.4s|\n' a ab abc abcd abcde
|   a|
|  ab|
| abc|
|abcd|
|abcd|
$ printf '|%-4.4s|\n' a ab abc abcd abcde
|a   |
|ab  |
|abc |
|abcd|
|abcd|

열의 텍스트 서식을 지정하는 기타 유틸리티는 다음과 같습니다.POSIXexpand:

printf 'Network %s\t: %s\n' "$hostname" "$state" | expand -t 30

\t(여기서 탭은 30열( )마다 확장되며 탭 정지가 사용됩니다.)

또는BSDcolumn또는POSIXpr:

printf 'Network %s\n: %s\n' "$hostname" "$state" | pr -at2

(여기서 출력은 36열 너비의 2열입니다( -w페이지 너비 기본값인 72를 변경하는 옵션 참조).

또는BSDrs:

{
   while...
      printf 'Network %s\n: %s\n' "$hostname" "$state"
   done
} | rs -e 0 2

( column모든 입력을 읽을 때까지 출력이 시작되지 않는 것과 같습니다.)

또는암소 비슷한 일종의 영양columns:

printf 'Network %s\n: %s\n' "$hostname" "$state" | columns -w 25 -c 2

zsh문자열 패딩을 위한 몇 가지 매개변수 확장 플래그도 있습니다 ${(l[15])hostname}:왼쪽패딩 ${(r[15])hostname}옳은패딩(잘림 포함). 이 플래그가 추가되면 m패딩은 문자의 표시 너비를 고려하는 반면, 플래그가 없으면 모든 문자의 표시 너비가 동일한 것으로 가정됩니다.

존재하다급속한 확장( 프롬프트나 플래그를 사용한 매개변수 확장에서 print -P활성화됨 %) %F{green}색상 출력도 지원하므로 다음을 수행할 수 있습니다.

online='%F{green}online%f'
printf '%s\n' "Network ${(r[15])hostname}: ${(%)online}"

또는:

print -rP "Network ${(r[15])hostname}: $online"

의 내용 $hostname도 프롬프트 확장의 영향을 받지만 promptsubst이 옵션이 활성화되어 있고 의 내용을 사용자가 제어할 수 없는 경우 이는 명령 주입 취약점이 됩니다 $hostname(예: ).hostname='$(reboot)'

답변2

간단하게column주문하다:

yourscript.sh | column -t

산출:

Network  10.x.xx.xxx     :  Online
Network  10.x.xx.xxx     :  Offline
Network  10.x.xx.xxx     :  Offline
Network  10.x.xx.xxx     :  Offline
Network  10.x.xx.x       :  Online
Network  139.xxx.x.x     :  Online
Network  208.xx.xxx.xxx  :  Online
Network  193.xxx.xxx.x   :  Online

답변3

\t열을 이동할 위치(탭 문자)에 숫자 집합을 삽입하도록 스크립트를 업데이트하세요 .

다음과 유사한 출력이 원하는 정렬을 제공합니다.

Network 10.x.xx.xxx\t: Online   
Network 10.x.xx.xxx\t: Offline   
Network 10.x.xx.xxx\t: Offline   
Network 10.x.xx.xxx\t: Offline   
Network 10.x.xx.x\t: Online   
Network 139.xxx.x.x\t: Online   
Network 208.xx.xxx.xxx\t: Online   
Network 193.xxx.xxx.x\t: Online

답변4

@Roman보다 훨씬 낫습니다.

yourscript.sh | column -t -s $'\t'

그런 다음 각 행을 추가하여 \t열로 분할합니다.

관련 정보