[bash] 같은 줄에 에코를 표시하고 업데이트하는 방법

Bash에 다음이 있습니다 (Linux)

for dir in Movies/*
do
  (cd "$dir" && pwd|cut -d \/ -f5|tr -s '\n' ', ' >> ../../movielist &&
  exiftool * -t -s3 -ImageSize -FileType|tr -s '\t' ',' >> ../../movielist )
echo "Movie $movies - $dir ADDED!"
let movies=movies+1
done

하지만 “echo”가 다음 줄에 다음 에코를 표시하도록 만들고 싶습니다 (마지막 에코 출력과 연결되지 않고 교체). 업데이트중인 것처럼 보이게합니다. 백분율이있는 진행률 표시 줄이 같은 줄에 표시되는 것과 비슷합니다.



답변

나는 man echo이것에 대한 페이지를 올바르게 읽지 못했습니다 .

echo에는 세 번째 이스케이프 문자를 추가하면이를 수행 할 수있는 두 가지 옵션이 있습니다.

두 가지 옵션은 -n-e입니다.

-n후행 개행을 출력하지 않습니다. 그래서 내가 무언가를 에코 할 때마다 새 줄로 이동하지 않아도됩니다.

-e 백 슬래시 이스케이프 기호를 해석 할 수 있습니다.

이것을 위해 어떤 이스케이프 기호를 사용하고 싶은지 맞춰보세요 : \r. 예, 캐리지 리턴은 저를 처음으로 돌려 보내고 동일한 라인에서 업데이트하는 것처럼 시각적으로 보일 것입니다.

따라서 에코 라인은 다음과 같습니다.

echo -ne "Movie $movies - $dir ADDED!"\\r

나는 Bash가 그것을 죽이지 않도록 탈출 기호를 탈출해야했다. 그래서 \거기에 2 개의 기호가 있습니다.

William이 언급했듯이, printf이와 같은 유사한 (그리고 훨씬 더 광범위한) 작업도 수행 할 수 있습니다.


답변

내가 잘 이해했다면 에코를 다음 줄로 바꿀 수 있습니다.

echo -ne "Movie $movies - $dir ADDED! \033[0K\r"

다음은 그 동작을 이해하기 위해 실행할 수있는 작은 예입니다.

#!/bin/bash
for pc in $(seq 1 100); do
    echo -ne "$pc%\033[0K\r"
    sleep 1
done
echo


답변

나머지 답변은 꽤 좋지만 누군가가 여기에 여러 줄 에코를 교체 / 업데이트하는 솔루션을 찾는 경우에 대비하여 추가 정보를 추가하고 싶었습니다.

그래서 저는 여러분 모두에게 예를 공유하고 싶습니다. 다음 스크립트는 CentOS 시스템에서 시도되었으며 기본적으로 시스템의 자세한 시간 정보를 인쇄하는 “timedatectl”명령을 사용합니다.

출력에 여러 줄이 포함되어 있고 아래 예제에서 완벽하게 작동하므로 해당 명령을 사용하기로 결정했습니다.

#!/bin/bash
while true; do
  COMMAND=$(timedatectl) #Save command result in a var.
  echo "$COMMAND" #Print command result, including new lines.

  sleep 3 #Keep above's output on screen during 3 seconds before clearing it

  #Following code clears previously printed lines
  LINES=$(echo "$COMMAND" | wc -l) #Calculate number of lines for the output previously printed
  for (( i=1; i <= $(($LINES)); i++ ));do #For each line printed as a result of "timedatectl"
    tput cuu1 #Move cursor up by one line
    tput el #Clear the line
  done

done

위는 ” timedatectl” 의 결과를 영원히 인쇄 하고 이전 에코를 업데이트 된 결과로 대체합니다.

이 코드는 예일 뿐이지 만 필요에 따라 최상의 솔루션이 아닐 수도 있습니다. 거의 동일하게 (적어도 시각적으로) 수행하는 유사한 명령은 ” watch -n 3 timedatectl“입니다.

그러나 그것은 다른 이야기입니다. 🙂

도움이 되었기를 바랍니다.


답변

이것은 유용하게 다양합니다. 시도하고 필요에 따라 변경하십시오.

#! bin/bash
for load in $(seq 1 100); do
    echo -ne "$load % downloded ...\r"
    sleep 1
done
echo "100"
echo "Loaded ..."


답변

이거 해봐도 돼 .. 나만의 버전 ..

funcc() {
while true ; do 
for i in \| \/ \- \\ \| \/ \- \\; do 
  echo -n -e "\r$1  $i  "
sleep 0.5
done  
#echo -e "\r                                                                                      "
[ -f /tmp/print-stat ] && break 2
done
}

funcc "Checking Kubectl" & &>/dev/null
sleep 5
touch /tmp/print-stat
echo -e "\rPrint Success                  "


답변

내가 가장 좋아하는 방법은 do the sleep to 50입니다. 여기서 i변수는 echo 문 내에서 사용해야합니다.

for i in $(seq 1 50); do
  echo -ne "$i%\033[0K\r"
  sleep 50
done
echo "ended"


답변