루트가 소유한 파일의 마지막 줄을 삭제합니다.

루트가 소유한 파일의 마지막 줄을 삭제합니다.

666사용자가 다른 스크립트를 사용하여 편집할 수 있도록 권한이 있는 파일이 있습니다 . 이것은 작동합니다. 파일의 마지막 줄을 제거하는 스크립트를 작성해야 하지만 sedtris와 같은 것을 사용하여 먼저 파일을 생성하고 제자리로 이동하는 것처럼 작동하지 않습니다. 사용자는 이 작업을 수행할 수 없습니다.

새 파일을 해당 위치로 이동하지 않고 파일을 편집하여 마지막 줄을 제거할 수 있는 방법이 있습니까?

답변1

이 질문에 태그가 지정되었으므로, 편집기를 사용하여 파일을 내부에서 편집하는 방법은 다음과 같습니다 ed.

printf '%s\n' d w q | ed -s file

를 사용하여 편집 세션을 시작하면 ed편집기는 항상 열려 있는 파일의 마지막 줄에 사용자를 배치합니다. 파일의 마지막 줄을 삭제하려면 삭제할 수 있습니다.현재의line을 사용하여 d수정된 버퍼를 파일에 다시 쓴 다음 w를 사용하여 종료합니다 q. 대부분의 편집기 구현 ed( BusyBox 제외 )에서는 다음 대신 ed비표준 조합 명령을 사용할 수 있습니다 .wqwq

이는 새 파일을 생성하지 않습니다(결과 파일은 원본 파일과 동일한 inode 번호를 갖습니다).

답변2

그 자리에서 잘라낼 수 있습니다. GNU 시스템에서:

truncate -s -"$(tail -n1 file | wc -c)" file

truncate -<n>깎다<n>파일 끝에 있는 바이트입니다. 여기<n>반환된 마지막 행의 길이(바이트)에서 계산됩니다 wc.

이식 가능한 경우 다음을 사용하여 perl잘라낼 수 있습니다.

tail -n1 file | perl -ne '
  if (seek(STDOUT, -length, 2)) {
    truncate STDOUT, tell STDOUT or die "truncate: $!\n"
  } else {
    die "seek: $!\n"
  }' 1<> file

파일의 내용을 다시 쓰지 않으므로 sed기반 방법보다 더 효율적입니다(그리고 텍스트가 아닌 파일이나 전체 파일 시스템에 직면할 때에도 더 안전합니다).

답변3

이를 파악하여 일반 sed 명령의 출력을 사용자의 로컬 파일(임시 파일)로 보낸 다음 해당 파일을 관련 파일에 출력으로 보냅니다.

sed '$d' /path/to/file > ./tempfile; cat ./tempfile > /path/to/file

답변4

임시 파일을 생성하지 않고 sed에서 "w" 명령을 사용하여 이를 수행하는 방법이 있습니다. 이렇게 하면 파일의 inode 번호가 변경되지 않습니다. 특히 스크립트에서 사용하기 쉬운 더 나은 버전 B)는 먼저 파일 이름을 변수에 할당하는 것입니다.

A) cat file|sed -ne '1h;${x;wfile' -e '};1!H'
B) file="test.txt";cat "$file"|sed -ne '1h;${x;w'"$file" -e '};1!H'

sed가 수정하려는 파일에서 직접 입력을 읽는 대신 파이프에서 입력을 읽을 수 있도록 파일이 cat에 전달됩니다. sed가 읽은 각 입력 줄은 예약된 공간에 저장됩니다. 그러나 입력이 끝나면 마지막 줄이 저장되기 전에 공간이 예약되어 파일에 기록됩니다.

관련 정보