次の.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,
この番号を削除する賢明な方法はありますか? Ubuntu 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はそれを1つの単位として扱うrotor
機能を持ちますbatch
。 Rakuはまた、規則性の低い節のための「トリガー」演算子を提供します。開始点については、下記のリンクをご覧ください。
https://docs.raku.org/言語/regexes
https://docs.raku.org/言語/regexes#Capture_markers:_%3C(_)%3E
https://raku.org