비어 있지 않은 마지막 줄의 텍스트를 바꾸는 방법은 무엇입니까?

비어 있지 않은 마지막 줄의 텍스트를 바꾸는 방법은 무엇입니까?

파일의 마지막 텍스트 줄을 찾아 끝의 쉼표를 제거하고 싶습니다. 나이 질문은 이미 요청되었습니다.그러나 답변을 받은 후에는 내 질문이 충분히 구체적이지 않다는 것을 깨달았습니다.

sed명령은 파일의 마지막 줄로 이동하여 작업을 수행합니다. 제 경우에는 후행 쉼표를 제거하고 싶습니다.

sed -i '$ s/",/"/g' file.txt

그래서 이거:

blah blah blah,
blah blah blah,
blah blah blah,

...다음과 같이 됩니다:

blah blah blah,
blah blah blah,
blah blah blah

하지만,텍스트의 마지막 줄 뒤에 빈 줄이 있으면 작동하지 않습니다.파일에서.

나는 텍스트의 마지막 줄을 얻을 수 있는 방법을 찾고 있었지만 내가 이해하고 적용할 수 있는 어떤 것도 찾지 못했습니다. 또한 모든 후행 공백 줄을 제거하는 방법을 찾고 다음 명령을 찾았습니다.

sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' *.txt

그러나 그것은 나에게는 작동하지 않습니다(명령줄에 내 파일의 내용을 출력하는 것 같습니다). 어쨌든 이것은 우아하지 않습니다. 뒤에 오는 빈 줄을 제거하고 싶지는 않습니다. 텍스트가 포함된 마지막 줄을 식별하고 그에 따라 조치를 취하는 것이 더 나을 것입니다.

마지막 줄에서 쉼표를 제거하는 방법텍스트하나의 디렉토리에 여러 파일이 있습니까?

답변1

대용량 파일의 경우 더 빠른 Guru의 답변을 사용하세요. 그러나 작은 파일(25줄 미만)에서는 이것이 약간 더 빠르다는 것을 알았습니다(GNU tac이 있다고 가정).

tac file | awk '!/^[[:blank:]]*$/{i++;if(i==1){sub(",$","")}}1' | tac

답변2

답변

perl -0777 -p -i -e 's/,(\n*)\Z/\1/m' *.txt

.txt마지막 ',' 는 ',' 뒤에 0개 이상의 줄 바꿈만 있고 파일의 끝이 오면 ',' 로 끝나는 모든 파일에서 제거됩니다 .

귀하의 예에서 :

reedm@www:~/tmp $ cat > test.txt
blah blah blah,
blah blah blah,
blah blah blah,


reedm@www:~/tmp $ perl -0777 -p -i -e 's/,(\n*)\Z/\1/m' *.txt
reedm@www:~/tmp $ cat test.txt
blah blah blah,
blah blah blah,
blah blah blah


reedm@www:~/tmp $ 

와트?

Perl은 최고의 순간에 난해한 짐승이며 Perl의 농담은 특히 비밀스러울 수 있습니다.

-e플래그를 사용하면 명령줄에서 Perl 프로그램을 전달할 수 있습니다. 이 경우 "s/regex/replace/flags"가 프로그램입니다.

이 플래그는 Perl이 제공된 각 파일 이름의 각 "줄" -p에 루프로 제공한 프로그램을 적용하도록 합니다 (참고자료 참조).-0

-i플래그는 Perl이 출력을 표준 출력으로 인쇄하는 대신 파일을 프로그램의 출력으로 바꾸도록 합니다.

-0플래그는 파일을 "라인"으로 구분하기 위해 Perl이 사용하는 구분 기호를 변경합니다. 0777관례에 따라 사용될 때 Perl이 전체 ​​파일을 단일 "줄"로 읽도록 하는 특수 값입니다.

정규식은 일부 Perl 관련 트릭으로 인해 약간 복잡합니다.

  • 첫째, m끝에 있는 플래그로 인해 정규 표현식이 여러 줄에서 실행됩니다.
  • ,간단하며 단일 쉼표와 일치합니다.
  • (\n*)한 줄에서 0개 이상의 개행 문자를 일치시키고 이를 하위 패턴( ()하위 패턴을 나타내는 문자)으로 저장합니다. 이것이 첫 번째 하위 패턴이므로 \1교체 섹션에서 "이 하위 패턴이 일치하는 모든 것"을 의미하는 데 사용할 수 있습니다.
  • \ZPerl 전용 확장자이며 사용되는 문자열의 끝과 일치합니다. 이 경우 전체 파일입니다.
  • 교체 부분에서는 \1일치 항목을 일련의 개행 문자로 바꾸고 쉼표를 제거합니다.

Perl 정규식 및 Perl 명령줄 플래그에 대한 자세한 내용은 perlre및 각각의 매뉴얼 페이지를 참조하십시오 perlrun.

답변3

Perl 솔루션이 귀하에게 적합한 경우:

 perl -00pe 's/(.*),/$1/s' file

파일 자체의 변경 사항을 저장하려면 다음을 수행하십시오.

perl -i -00pe 's/(.*),/$1/s' file

여러 파일에 적용하려면:

perl -i -00pe 's/(.*),/$1/s' *.txt

답변4

sed전체 파일 내용을 "패턴 공간"에서 한 줄로 처리할 수 있도록 여러 줄 검색 및 바꾸기 모드로 들어갈 수 있습니다.

(참고: FreeBSD에서는 올바른 내부 파일 편집을 위해 sed옵션 순서가 필요합니다 .)-n -i -e

# delete the last , in the last non-empty line of a file
# cf. http://austinmatzko.com/2008/04/26/sed-multi-line-search-and-replace/

cat -n testfile

sed -n -i -e '
# if the first line copy the pattern to the hold buffer
1h
# if not the first line then append the pattern to the hold buffer
1!H
# if the last line then ...
$ {
# copy from the hold to the pattern buffer
g
# remove last , in last non-empty line of file 
#s/,\([^,[:cntrl:]]*\n*\)$/\1/
s/,\([^,]*\)$/\1/
p
}' testfile

관련 정보