요약
줄 바꿈없이 줄을 인쇄하고 인쇄 할 다른 줄이있는 경우에만 줄 바꿈을 추가하십시오.
$ printf 'one\ntwo\n' |
awk '{ printf( "%s%s" , NR>1?"\n":"" , $0 ) }'; echo " done"
one
two done
다른 솔루션
파일로 작업하는 경우 한 줄의 문자 만 잘라낼 수 있습니다 (줄 바꿈으로 끝나는 경우).
removeTrailNewline () {[[$ (tail -c 1 "$ 1")]] || 잘라 내기 -s-1 "$ 1"; }
파일에서 한 문자 만 truncate
읽은 다음 전체 파일을 읽지 않고 직접 제거 ( ) 해야하므로 빠른 솔루션 입니다.
그러나 stdin (스트림)의 데이터로 작업하는 동안 데이터를 모두 읽어야합니다. 그리고 읽히자 마자 "소비"됩니다. 역 추적 없음 (잘라내 기와 동일). 스트림의 끝을 찾으려면 스트림의 끝을 읽어야합니다. 이 시점에서 입력 스트림을 다시 이동할 수있는 방법이 없으며 데이터는 이미 "소비"되었습니다. 데이터가 있음이 의미 한다 우리는 스트림의 끝과 일치 할 때까지 버퍼의 일부 형태로 저장 될 버퍼의 데이터와 뭔가.
가장 확실한 해결책은 스트림을 파일로 변환하고 해당 파일을 처리하는 것입니다. 그러나 질문은 일종의 스트림 필터를 요구합니다. 추가 파일 사용에 관한 것이 아닙니다.
변하기 쉬운
순진한 솔루션은 전체 입력을 변수로 캡처하는 것입니다.
FilterOne(){ filecontents=$(cat; echo "x"); # capture the whole input
filecontents=${filecontents%x}; # Remove the "x" added above.
nl=$'\n'; # use a variable for newline.
printf '%s' "${filecontents%"$nl"}"; # Remove newline (if it exists).
}
printf 'one\ntwo' | FilterOne ; echo 1done
printf 'one\ntwo\n' | FilterOne ; echo 2done
printf 'one\ntwo\n\n' | FilterOne ; echo 3done
기억
sed를 사용하여 전체 파일을 메모리에로드 할 수 있습니다. sed에서는 마지막 줄에서 후행 줄 바꿈을 피할 수 없습니다. GNU sed는 후행 줄 바꿈 인쇄를 피할 수 있지만 소스 파일이 이미없는 경우에만 가능합니다. 따라서 간단한 sed는 도움이되지 않습니다.
-z
옵션 이있는 GNU awk를 제외하고 :
sed -z 's/\(.*\)\n$/\1/'
awk (임의의 awk)를 사용하면 전체 스트림을 슬러그 처리합니다 printf
.
awk ' { content = content $0 RS }
END { gsub( "\n$", "", content ); printf( "%s", content ) }
'
전체 파일을 메모리에로드하는 것은 좋은 생각이 아닐 수 있으며 많은 메모리를 소비 할 수 있습니다.
메모리에 두 줄
awk에서는 변수에 이전 줄을 저장하고 현재 줄을 인쇄하여 루프 당 두 줄을 처리 할 수 있습니다.
awk 'NR>1{print previous} {previous=$0} END {printf("%s",$0)}'
직접 처리
그러나 우리는 더 잘할 수있었습니다.
줄 바꿈없이 현재 줄을 인쇄하고 다음 줄이있을 때만 줄 바꿈을 인쇄하면 한 번에 한 줄씩 처리하며 마지막 줄 에는 줄 바꿈 줄이 없습니다 .
awk 'NR == 1 {printf ( "% s", $ 0); 다음}; {printf ( "\ n % s", $ 0)} '
또는 다른 방법으로 작성하십시오.
awk 'NR>1{ print "" }; { printf( "%s", $0 ) }'
또는:
awk '{ printf( "%s%s" , NR>1?"\n":"" , $0 ) }'
그래서:
$ printf 'one\ntwo\n' | awk '{ printf( "%s%s" , NR>1?"\n":"" , $0 ) }'; echo " done"
one
two done
chomp
하므로 이는와 정확히 동일하지 않습니다chomp
.