표적: 각 주석 블록의 마지막 줄을 제외한 모든 주석 줄을 제거합니다. 파일이 주석 블록으로 끝나면 완전히 삭제하십시오. 각 주석 줄은 으로 시작합니다
#
.내가 시도한 명령
sed -z -e 's/#.*\n#/#/g' "${InputP}"
입력 파일
# Life/Living # Life/Passion - [Mindfulness.md](file:///home/nikhil/Documents/Git/Life/Passion/PassionSrc/Sports/Yoga/Mindfulness/Mindfulness.md) # Life/PersonalManagement # Life/Social # Linux/AmazingNotes # Linux/Backintime # Linux/DotFiles # Linux/GitScripts - [Peaceful.m3u](file:///home/nikhil/Documents/Git/../Mobile/Documents/PortableNotes/PortableNotesSrc/SocialActivity/Music/SongsPlaylist/Data/Peaceful.m3u) - [AuxiliaryFiles.sh](file:///home/nikhil/Documents/Git/Linux/GitScripts/GitScriptsSrc/GitInit/GitNew/Src/AuxiliaryFiles.sh) # PythonWs/NumericalProgramming # PythonWs/Python # PythonWs/ScientificComputing
예상 출력
# Life/Passion - [Mindfulness.md](file:///home/nikhil/Documents/Git/Life/Passion/PassionSrc/Sports/Yoga/Mindfulness/Mindfulness.md) # Linux/GitScripts - [Peaceful.m3u](file:///home/nikhil/Documents/Git/../Mobile/Documents/PortableNotes/PortableNotesSrc/SocialActivity/Music/SongsPlaylist/Data/Peaceful.m3u) - [AuxiliaryFiles.sh](file:///home/nikhil/Documents/Git/Linux/GitScripts/GitScriptsSrc/GitInit/GitNew/Src/AuxiliaryFiles.sh)
- 하지만 나는 이 출력을 얻습니다.
# PythonWs/ScientificComputing
이 문제를 해결하는 방법을 아는 사람이 있나요?
답변1
문제는 .*
욕심이 많아서 를 sed -z -e 's/#.*\n#/#/g'
포함하는 첫 번째 줄부터 #
로 시작하는 마지막 줄까지 일치한다는 것입니다 #
. 이는 -z
패턴 공간의 전체 파일을 한 번에 흡수하는 플래그 때문에 발생합니다(텍스트 파일에 null 바이트가 없다고 가정).
문제를 해결하는 Sed 스크립트는 다음과 같습니다.
sed -n '/^#/N;/\n#/D;p' file
/^#/N
행이 로 시작하면#
다음 행이 패턴 공간에 추가됩니다./\n#/D
패턴 공간에 newline과 newline이 포함된 경우#
newline 앞의 모든 항목을 삭제하고 새 루프를 시작합니다.p
이 명령에 도달하면 패턴 공간이 인쇄됩니다.
유용한 링크
답변2
입력에서 다른 주석 줄이 뒤에 오는 모든 주석 줄을 분명히 제거하려고 합니다. sed
기본적으로 정규식이 사용되므로 호출이 실패합니다."탐욕스러운"(즉, 가능한 한 많이 소비), 이는 변경하기 쉽지 않습니다.
awk
따라서 명시된 목표에 대한 기반 솔루션을 추가 하겠습니다 .
awk '/^#/{buf=$0;next} {if (buf) {print buf; buf=""}}1' "${InputP}"
또는 약간 더 컴팩트합니다.
awk '/^#/{buf=$0;next} buf{print buf; buf=""}1' "${InputP}"
- 이렇게 하면 주석 줄이 아닌 모든 줄이 인쇄됩니다(
1
규칙 블록 외부는 "지금까지 수정된 모든 내용을 포함하여 현재 줄을 인쇄합니다"를 의미합니다. 이 경우에는 아무 것도 없습니다). - 패턴과 일치하는 주석 행이 발견되면
/^#/
내용은 버퍼에 저장되지만buf
아직 인쇄되지는 않습니다. 명령next
은 다음 실행 줄로 이동하므로 나머지 코드는 주석 처리되지 않은 줄에만 적용됩니다. - 주석이 아닌 줄이 나타나면 버퍼 내용(있는 경우)이 먼저 인쇄되고 실제 줄 내용을 인쇄하기 전에 버퍼가 비워집니다(여러 인쇄를 방지하기 위해).
답변3
GNU sed
후루룩 소리 모드를 사용 -z
하고 확장 정규식을 활용하면 -E
다음을 수행할 수 있습니다.
$ sed -Ez '
s/(^|\n)(#[^\n]*\n)+$/\1/
s/(^|\n)(#[^\n]*\n)+/\1\2/g
' file
- 후행 주석 블록을 제거합니다.
- 모든 주석 블록을 제거하되 각 주석 블록의 마지막 줄은 유지합니다.
GNU sed 모델은 다음과 같습니다:
- sed는 파일을 한 줄씩 읽습니다.
-z
그렇지 않으면 유효하지 않은 경우 전체 파일을 읽습니다. 레코드 구분 기호는 기본적으로 개행으로 설정되며, ASCII를 사용\n
하지 않는 한 NULL 입니다.-z
\0
- 레코드를 읽은 후 후행 레코드 구분 기호가 잘리고 결과 문자열이 패턴 공간 레지스터에 저장됩니다. 패턴 공간은 모든 sed 명령이 실행되는 곳입니다.
sed
이제 스크립트에 5개의 명령이 있다고 가정해 보겠습니다sed
. 첫 번째 명령은 패턴 공간에 적용되어 패턴 공간을 수정하고,sed
다음 명령은 이 수정된 패턴 공간에 적용되며, 마지막 명령까지 계속됩니다. 그런 다음 유효stdout
하지 않은-n
패턴 공간이 인쇄됩니다 . 그 후, 다음 레코드를 읽고 동일한sed
명령 순서가 패턴 공간에 적용됩니다.
위의 내용은 스크립트에서 흐름 제어 명령이 사용되지 않을 때 유효한 매우 단순화된 설명입니다 sed
.
예, 맞습니다. 후루룩 소리 모드에서는 $
패턴 공간이 하나만 있기 때문에 파일의 끝과 패턴 공간의 끝을 나타냅니다.
이 구문이 있으면 (regex)+
정규식의 욕심 많은 특성으로 인해 괄호가 마지막 정규식 일치를 유지합니다.
또는 다음을 수행할 수 있습니다.
$ sed -e '
/^#/{h;d;}
H;z;x;s/^\n//
' file
답변4
이것은 작동합니다:
perl -ne 'print $x,$_ unless /^#/; $x = /^#/ ? $_ : ""' < infile
게시 한 예상 결과를 얻었습니다.
편집 : 설명
- 당신이 원한다면 그것을 고려하십시오
$x
:-)$left_over_line_to_be_printed
- 첫 번째 문은 나머지 줄을 모두 인쇄한 다음 현재 줄을 인쇄합니다(현재 줄이 헤더 줄이 아닌 경우).
- 두 번째 문은 "leftover"를 표시된 마지막 헤더 행 또는 빈 문자열로 설정합니다. (즉, 헤더 행이 아닌 경우 "remaining"은 첫 번째 문에서 이미 인쇄되었기 때문에 빈 문자열이 됩니다. 헤더 행의 경우 해당 행이 됩니다. 여러 헤더 행이 함께 클러스터링되면 결국에는 마지막이 된다).