[linux] 줄 바꿈이 파일의 마지막 문자 인 경우 어떻게 삭제합니까?

마지막 줄 바꿈이 파일의 마지막 문자 인 경우 삭제하려는 일부 파일이 있습니다. od -c내가 실행하는 명령이 새로운 줄로 파일을 작성한다는 것을 보여줍니다.

0013600   n   t  >  \n

sed로 몇 가지 트릭을 시도했지만 생각할 수있는 최선은 트릭을 수행하지 않는 것입니다.

sed -e '$s/\(.*\)\n$/\1/' abc

이 작업을 수행하는 방법에 대한 아이디어가 있습니까?



답변

perl -pe 'chomp if eof' filename >filename2

또는 파일을 제자리에 편집하려면 다음을 수행하십시오.

perl -pi -e 'chomp if eof' filename

[편집자 주 : -pi -e원래 -pie는 였지만 여러 주석가가 언급하고 @hvd가 설명했듯이 후자는 작동하지 않습니다.]

이것은 내가 본 awk 웹 사이트에서 ‘펄 신성 모독’으로 묘사되었습니다.

그러나 테스트에서 효과가있었습니다.


답변

명령 대체가 후행 줄 바꾸기 문자를 제거 한다는 사실을 이용할 수 있습니다 .

bash, ksh, zsh에서 작동하는 간단한 형식 :

printf %s "$(< in.txt)" > out.txt

휴대용 (POSIX 호환) 대안 (약간 덜 효율적) :

printf %s "$(cat in.txt)" > out.txt

노트 :


다른 답변에 가이드 :

  • Perl 을 사용할 수 있다면 허용되는 답변을 찾으 십시오. 간단하고 메모리 효율적입니다 (전체 입력 파일을 한 번에 읽지 않음).

  • 그렇지 않으면, ghostdog74의 Awk 답변을 고려 하십시오모호하지만 메모리 효율적입니다 . 더 읽기 상당 (POSIX 호환)입니다 :

    • awk 'NR > 1 { print prev } { prev=$0 } END { ORS=""; print }' in.txt
    • END블록 에서 최종 행을 처리 할 수 ​​있도록 인쇄가 한 줄 지연되어 \n출력 레코드 구분 기호 ( OFS)를 빈 문자열 로 설정하여 후행없이 인쇄 합니다.
  • 원본을 대체하는 임시 파일을 작성하는 대신 실제로 편집 하는 상세하지만 빠르고 강력한 솔루션을 원한다면 jrockway의 Perl 스크립트를 고려하십시오 .


답변

headGNU coreutils 에서이 작업을 수행 할 수 있으며 파일 끝과 관련된 인수를 지원합니다. 마지막 바이트 사용을 피하려면 :

head -c -1

끝나는 줄 바꿈을 테스트하려면 tail및 을 사용할 수 있습니다 wc. 다음 예제는 결과를 임시 파일에 저장 한 후 원본을 덮어 씁니다.

if [[ $(tail -c1 file | wc -l) == 1 ]]; then
  head -c -1 file > file.tmp
  mv file.tmp file
fi

“in-place”편집을 위해 spongefrom moreutils을 사용할 수도 있습니다 .

[[ $(tail -c1 file | wc -l) == 1 ]] && head -c -1 file | sponge file

.bashrc파일에 이것을 넣어서 일반적인 재사용 가능한 기능을 만들 수도 있습니다.

# Example:  remove-last-newline < multiline.txt
function remove-last-newline(){
    local file=$(mktemp)
    cat > $file
    if [[ $(tail -c1 $file | wc -l) == 1 ]]; then
        head -c -1 $file > $file.tmp
        mv $file.tmp $file
    fi
    cat $file
}

최신 정보

에서 언급 한 바와 같이 KarlWilbur 의견과에서 사용 Sorentar의 대답 , truncate --size=-1대체 할 수 head -c-1및 현재 위치에서 지원은 편집.


답변

head -n -1 abc > newfile
tail -n 1 abc | tr -d '\n' >> newfile

편집 2 :

다음은 잠재적으로 거대한 배열을 축적하지 않는 awk버전 (수정) 입니다.

awk ‘{if (라인) 인쇄 라인; line = $ 0} 끝 {printf $ 0} ‘abc


답변

둔한 사람

   awk '{q=p;p=$0}NR>1{print q}END{ORS = ""; print p}' file


답변

coreutils의 GNU echo가 필요한 단일 행 파일을위한 매우 간단한 방법 :

/bin/echo -n $(cat $file)


답변

제대로하려면 다음과 같은 것이 필요합니다.

use autodie qw(open sysseek sysread truncate);

my $file = shift;
open my $fh, '+>>', $file;
my $pos = tell $fh;
sysseek $fh, $pos - 1, 0;
sysread $fh, my $buf, 1 or die 'No data to read?';

if($buf eq "\n"){
    truncate $fh, $pos - 1;
}

읽고 추가하기 위해 파일을 엽니 다. 추가를 위해 여는 seek것은 파일의 끝 부분에 이미 들어 갔음을 의미 합니다. 그런 다음 파일 끝의 숫자 위치를로 얻습니다 tell. 이 숫자를 사용하여 한 문자를 찾은 다음 그 문자를 읽습니다. 줄 바꿈이면 파일을 줄 바꿈 앞의 문자로 자릅니다. 그렇지 않으면 아무것도하지 않습니다.

이것은 모든 입력에 대해 일정한 시간과 일정한 공간에서 실행되며 더 이상 디스크 공간이 필요하지 않습니다.