[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
노트 :
- 경우
in.txt
에 끝 여러 줄 바꿈 문자, 명령 치환은 제거 모든 중 – 덕분에, @Sparhawk을. 후행 줄 바꿈 이외의 공백 문자는 제거하지 않습니다. - 이 방법 은 전체 입력 파일을 메모리로 읽으 므로 더 작은 파일에만 권장됩니다.
printf %s
줄 바꿈이 출력에 추가되지 않도록합니다 (비표준의 POSIX 호환 대안입니다echo -n
. http://pubs.opengroup.org/onlinepubs/009696799/utilities/echo.html 및 https : //unix.stackexchange 참조). com / a / 65819 )
다른 답변에 가이드 :
-
Perl 을 사용할 수 있다면 허용되는 답변을 찾으 십시오. 간단하고 메모리 효율적입니다 (전체 입력 파일을 한 번에 읽지 않음).
-
그렇지 않으면, ghostdog74의 Awk 답변을 고려 하십시오 – 모호하지만 메모리 효율적입니다 . 더 읽기 상당 (POSIX 호환)입니다 :
awk 'NR > 1 { print prev } { prev=$0 } END { ORS=""; print }' in.txt
END
블록 에서 최종 행을 처리 할 수 있도록 인쇄가 한 줄 지연되어\n
출력 레코드 구분 기호 (OFS
)를 빈 문자열 로 설정하여 후행없이 인쇄 합니다.
-
원본을 대체하는 임시 파일을 작성하는 대신 실제로 편집 하는 상세하지만 빠르고 강력한 솔루션을 원한다면 jrockway의 Perl 스크립트를 고려하십시오 .
답변
head
GNU 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”편집을 위해 sponge
from 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
. 이 숫자를 사용하여 한 문자를 찾은 다음 그 문자를 읽습니다. 줄 바꿈이면 파일을 줄 바꿈 앞의 문자로 자릅니다. 그렇지 않으면 아무것도하지 않습니다.
이것은 모든 입력에 대해 일정한 시간과 일정한 공간에서 실행되며 더 이상 디스크 공간이 필요하지 않습니다.