로그 파일의 마지막 50줄을 유지하는 방법

로그 파일의 마지막 50줄을 유지하는 방법

파일의 마지막 50줄을 유지하고 매분마다 온도를 저장해 보았습니다. 나는 다음 명령을 사용했습니다.

tail -n 50 /home/pi/Documents/test > /home/pi/Documents/test

그러나 결과는 빈 테스트 파일입니다. 나는 그것이 테스트 파일의 마지막 50줄을 나열하고 그것을 테스트 파일에 삽입할 것이라고 상상합니다. 이 명령을 사용할 때:

tail -n 50 /home/pi/Documents/test > /home/pi/Documents/test2

잘 작동합니다. test2 파일에는 50줄이 있습니다.

누구든지 문제가 무엇인지 설명할 수 있습니까?

답변1

문제는 쉘이 명령을 실행하기 전에 명령 파이프라인을 설정한다는 것입니다. "입력 및 출력" 문제가 아니라 tail이 실행되기 전에 파일 내용이 사라지는 것입니다. 다음과 같이 진행됩니다.

  1. 쉘은 >쓰기 위해 출력 파일을 열고 이를 자릅니다.
  2. 쉘은 이 출력에 대해 파일 설명자 1(표준 출력용)을 설정합니다.
  3. 쉘 실행 tail.
  4. tail실행하고 열어보고 /home/pi/Documents/test아무것도 찾지 마세요.

많은 해결 방법이 있지만 핵심은 문제를 이해하고, 정확히 무엇이 잘못되고 있으며, 그 이유는 무엇인지 이해하는 것입니다.

그러면 당신이 찾고 있는 것이 나올 것입니다.

echo "$(tail -n 50 /home/pi/Documents/test)" > /home/pi/Documents/test

설명하다:

  • $()명령 대체라고 알려진 실행tail -n 50 /home/pi/Documents/test
  • 따옴표는 출력에서 ​​개행을 유지합니다.
  • > /home/pi/Documents/test출력을 echo "$(tail -n 50 /home/pi/Documents/test)"동일한 파일로 리디렉션합니다.

답변2

파일 리디렉션 파일을 먼저 지우는 또 다른 솔루션은 다음을 sponge사용하는 것입니다.moreutils다음과 같이 포장하세요.

tail -n 50 /home/pi/Documents/test | sponge /home/pi/Documents/test

답변3

이는 bash가 리디렉션을 먼저 처리하여 >파일 내용을 삭제하기 때문입니다. 그런 다음 명령을 실행합니다. 를 사용하면 >>마지막 50줄이 파일의 현재 내용 끝에 추가됩니다. 이 예에서는 동일한 50개 행이 두 번 반복됩니다.

다른 파일로 리디렉션되면 명령이 예상대로 작동합니다. 다음은 파일의 마지막 50줄을 동일한 이름의 파일에 쓰는 한 가지 방법입니다.

tail -50 /home/pi/Documents/test > /home/pi/Documents/test2 && mv /home/pi/Documents/test2 /home/pi/Documents/test

먼저 마지막 50줄을 임시 파일에 쓴 다음 이를 이동하여 mv원본 파일을 대체합니다.

주석에서 지적했듯이 파일이 아직 열려 있으면 작동하지 않습니다. 파일을 이동하면 새 inode가 생성되고 소유권과 권한이 변경될 수도 있습니다. 임시 파일을 사용하여 이를 수행하는 더 좋은 방법은 다음과 같습니다.

tail -50 /home/pi/Documents/test > /home/pi/Documents/test2 ; cat /home/pi/Documents/test2 > /home/pi/Documents/test

임시 파일도 삭제할 수 있지만, 삭제될 때마다 해당 내용을 덮어씁니다.

답변4

이제 셸 리디렉션의 주요 문제를 이해했으므로 파일을 마지막 50줄로 자르는 또 다른 방법이 있습니다.

file=/path/to/the/file
n=$(( $(wc -l < "$file") - 50 ))
[[ $n -gt 0 ]] && sed -i 1,${n}d "$file"

이 어려운 작업은 -i(GNU) sed의 "제자리에서 편집" 기능에 의해 수행됩니다. 이 기능은 임시 파일에 출력을 생성하여 뒤에서 작동합니다. 나머지 줄은 sed 작업의 수학을 설정합니다. 즉:

  1. 파일( )의 줄 수를 세고 wc50을 뺍니다 n.
  2. 양수 이면 n sed 명령을 실행하여 라인 1부터 n까지 삭제합니다.

관련 정보