다음과 같은 .srt 파일이 있습니다.
입력 파일
1
00:00:17,920 --> 00:00:21,159
The essential is invisible to the eye. 3
2
00:00:21,160 --> 00:00:22,559
This phrase comes from 4
3
00:00:22,560 --> 00:00:25,039
As if saying goodbye saddens me, 5
각 대화 뒤에는 숫자가 있는 것을 볼 수 있습니다(예: '...eye.' 뒤에는 3이, '...from' 뒤에는 4가 옵니다). 이 숫자를 제거하고 싶습니다.
예상 출력 파일
1
00:00:17,920 --> 00:00:21,159
The essential is invisible to the eye.
2
00:00:21,160 --> 00:00:22,559
This phrase comes from
3
00:00:22,560 --> 00:00:25,039
As if saying goodbye saddens me,
이 번호를 삭제하는 현명한 방법이 있나요? 우분투 22.04를 사용하고 있습니다.
답변1
사용GNU awk
$ awk '/\s+[0-9]+\s*$/{NF--}1'
$ awk '{sub(/[[:space:]]+[0-9]+[[:space:]]*$/,"")}1'
또는
$ awk '/[[:alpha:]]+/ && $NF ~ /^[[:digit:]]+$/{$NF=""}1' file
답변2
모든 Unix 시스템의 모든 쉘에서 sed를 사용하십시오.
$ sed 's/ [0-9]*$//' file
1
00:00:17,920 --> 00:00:21,159
The essential is invisible to the eye.
2
00:00:21,160 --> 00:00:22,559
This phrase comes from
3
00:00:22,560 --> 00:00:25,039
As if saying goodbye saddens me,
원한다면 어떤 awk로도 동일한 작업을 수행할 수 있습니다.
awk '{sub(/ [0-9]*$/,"")}1' file
테스트를 위해 OP 예제 입력의 처음 3개 청크만 사용했습니다. 나머지 입력은 기본적으로 동일했기 때문에 예제가 복잡해졌습니다.
답변3
그리고 Perl
:
입력 파일:
1
00:00 --> 00:00
foo bar 10
2
00:00 --> 00:00
base qux 11
3
00:00 --> 00:00
aqw zdv 12
주문하다:
펄 --version
>= 5.36:
perl -g -pe 's/\d+(?=\n\s*\n)//g' file
펄 --version
<5.36:
perl -0777 -pe 's/\d+(?=\n\s*\n)//g' file
산출:
1
00:00 --> 00:00
foo bar
2
00:00 --> 00:00
base qux
3
00:00 --> 00:00
aqw zdv
정규식 일치는 다음과 같습니다.
마디 | 설명하다 |
---|---|
\d+ |
숫자(0~9)(1회 이상(최대한 많이 일치)) |
(?= |
시야다음이 있는지 확인하세요. |
\n |
'\n'(개행 문자) |
\s* |
공백(\n, \r, \t, \f 및 " ")(0회 이상(최대한 일치)) |
\n |
'\n'(개행 문자) |
) |
미리보기 끝 |
답변4
사용행복하다(이전 Perl_6)
~$ raku -e 'for slurp() { print S:g/ \s* \d+ <?before \n\s*\n > //};' file
#OR:
~$ raku -e 'print S:g/ \s* \d+ <?before \n\s*\n > // for slurp();' file
위 내용은 Perl 계열의 프로그래밍 언어인 Raku로 작성된 답변입니다. 기본적으로 저는 @GillesQuénot의 뛰어난 Perl 답변을 Raku로 다시 작성했습니다. Raku에는 개행 문자 등을 slurp
보존하면서 전체 파일을 한 번에 메모리로 읽을 수 있는 기능이 있습니다 (Perl의 명령줄 옵션과 유사). 그런 다음 여기에 철자가 표시된 Raku 버전의 전방 예측을 사용하는 것이 쉽습니다 (Raku는 공백을 허용하므로 정규식 원자 간격을 둘 수 있습니다).\n
-0777
<?before \n\s*\n >
사람들은 대체 연산자의 반환 값에 대해 종종 혼란스러워합니다. Raku는 S///
"big-S" 운영자를 제공하는 접근 방식을 취했습니다 .결과 문자열을 반환합니다.:global
또한 Raku에서는 or와 같은 정규식 수식자가 Perl처럼 연산자 뒤에 오는 것이 아니라 :g
연산자 앞에 온다는 점에 유의해야 합니다 .
참고: .srt
파일 사양에 대해 더 자세히 알지 못하면 <?before [\n\s*\n | \n$] >
Raku 미리보기를 사용하는 것이 더 안전할 것입니다. 이는 라인이더라도 라인을 올바르게 편집합니다.\n
파일의 마지막 전체 종료 줄(댓글에서 이 점을 지적해 주신 @tink에게 감사드립니다.)
입력 예:
1
00:00 --> 00:00
foo bar 10
2
00:00 --> 00:00
base qux 11
3
00:00 --> 00:00
aqw zdv 12
예제 출력:
1
00:00 --> 00:00
foo bar
2
00:00 --> 00:00
base qux
3
00:00 --> 00:00
aqw zdv
<( … )>
Raku의 또 다른 접근 방식은 캡처 태그를 사용하는 것입니다 .
~$ raku -e 'for slurp() { print S:g/ <( \s* \d+ )> \n\s*\n //};' file
#OR:
~$ raku -e 'print S:g/ <( \s* \d+ )> \n\s*\n // for slurp();' file
대상 파일에 대해 더 많이 알지 못하면 추가 방법을 제안하기가 어렵습니다. Perl에는 사용할 수 있는 "단락 모드"가 있습니다 .split(/ \n ** 2..* /)
. 각 "단락"이 3줄이면 Raku는 이를 하나의 단위로 처리 rotor
하는 기능을 갖습니다 batch
. Raku는 또한 덜 규칙적인 구절을 위한 "트리거" 연산자를 제공합니다. 시작 지점은 아래 링크를 참조하세요.
https://docs.raku.org/언어/regexes
https://docs.raku.org/언어/regexes#Capture_markers:_%3C(_)%3E
https://raku.org