Bash-script. Shift seconds
In bash I don't know how to do that. I need to do a bash-script. At stdin I have .srt file of subtitles in this format:
num
HH:MM:SS,SSS --> HH:MM:SS,SSS
text line 1
text line 2
...
HH:MM:SS,SSS start and finish of title for text.
Script must shift seconds. (it can be + or -)
Example:
$cat bmt.srt
5
00:01:02,323 --> 00:01:05,572
Hello, my frieds!
6
....
$./shifter.sh +3<mbt.srt
5
00:01:05,323 --> 00:01:08,572
Hello, my frieds!
6
I need to grab all HH:MM:SS and convert them to seconds firstly. Is somebody able do this without sed?
bash shell-script text-processing date
add a comment |
In bash I don't know how to do that. I need to do a bash-script. At stdin I have .srt file of subtitles in this format:
num
HH:MM:SS,SSS --> HH:MM:SS,SSS
text line 1
text line 2
...
HH:MM:SS,SSS start and finish of title for text.
Script must shift seconds. (it can be + or -)
Example:
$cat bmt.srt
5
00:01:02,323 --> 00:01:05,572
Hello, my frieds!
6
....
$./shifter.sh +3<mbt.srt
5
00:01:05,323 --> 00:01:08,572
Hello, my frieds!
6
I need to grab all HH:MM:SS and convert them to seconds firstly. Is somebody able do this without sed?
bash shell-script text-processing date
mplayer has some subtitle delay options, only I don't know if it can store it as new subtitle; still, I suspect there's an existing solution for this out there somewhere...
– frostschutz
Oct 17 '13 at 20:15
add a comment |
In bash I don't know how to do that. I need to do a bash-script. At stdin I have .srt file of subtitles in this format:
num
HH:MM:SS,SSS --> HH:MM:SS,SSS
text line 1
text line 2
...
HH:MM:SS,SSS start and finish of title for text.
Script must shift seconds. (it can be + or -)
Example:
$cat bmt.srt
5
00:01:02,323 --> 00:01:05,572
Hello, my frieds!
6
....
$./shifter.sh +3<mbt.srt
5
00:01:05,323 --> 00:01:08,572
Hello, my frieds!
6
I need to grab all HH:MM:SS and convert them to seconds firstly. Is somebody able do this without sed?
bash shell-script text-processing date
In bash I don't know how to do that. I need to do a bash-script. At stdin I have .srt file of subtitles in this format:
num
HH:MM:SS,SSS --> HH:MM:SS,SSS
text line 1
text line 2
...
HH:MM:SS,SSS start and finish of title for text.
Script must shift seconds. (it can be + or -)
Example:
$cat bmt.srt
5
00:01:02,323 --> 00:01:05,572
Hello, my frieds!
6
....
$./shifter.sh +3<mbt.srt
5
00:01:05,323 --> 00:01:08,572
Hello, my frieds!
6
I need to grab all HH:MM:SS and convert them to seconds firstly. Is somebody able do this without sed?
bash shell-script text-processing date
bash shell-script text-processing date
edited Nov 18 '18 at 19:19
Rui F Ribeiro
39.6k1479132
39.6k1479132
asked Oct 17 '13 at 20:08
GeorgyGeorgy
514
514
mplayer has some subtitle delay options, only I don't know if it can store it as new subtitle; still, I suspect there's an existing solution for this out there somewhere...
– frostschutz
Oct 17 '13 at 20:15
add a comment |
mplayer has some subtitle delay options, only I don't know if it can store it as new subtitle; still, I suspect there's an existing solution for this out there somewhere...
– frostschutz
Oct 17 '13 at 20:15
mplayer has some subtitle delay options, only I don't know if it can store it as new subtitle; still, I suspect there's an existing solution for this out there somewhere...
– frostschutz
Oct 17 '13 at 20:15
mplayer has some subtitle delay options, only I don't know if it can store it as new subtitle; still, I suspect there's an existing solution for this out there somewhere...
– frostschutz
Oct 17 '13 at 20:15
add a comment |
2 Answers
2
active
oldest
votes
Unless the subtitle file spans more than 24 hours, you can use date
for this:
#!/usr/bin/env bash
set -o errexit -o noclobber -o nounset -o pipefail
date_offset="$1"
shift_date() {
date --date="$1 $date_offset" +%T,%N | cut -c 1-12
}
while read -r line
do
if [[ $line =~ ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9] --> [0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9]$ ]]
then
read -r start_date separator end_date <<<"$line"
new_start_date="$(shift_date "$start_date")"
new_end_date="$(shift_date "$end_date")"
printf "%s %s %sn" "$new_start_date" "$separator" "$new_end_date"
echo "New date"
else
printf "%sn" "$line"
fi
done
For some reason you need to use decimal numbers with this, but it works:
$ ./shifter.sh "+3.0 seconds" < bmt.srt
5
00:01:05,323 --> 00:01:08,572
New date
Hello, my frieds!
6
add a comment |
Perl solution. I did not use any classical time handling module, as miliseconds handling is generally poorly supported.
#!/usr/bin/perl
use warnings;
use strict;
use constant FACTORS => (60 * 60 * 1000,
60 * 1000,
1000,
1);
sub time2ms {
my $time = shift;
my ($ms, $i) = (0, 0);
$ms += (FACTORS)[$i++] * $_ for split /[^0-9]/, $time;
return $ms;
}
sub ms2time {
my $ms = shift;
my $str = q();
for my $i (0 .. 3) {
$str .= sprintf +($i == 3 ? '%03d' : '%02d')
. (':', ':', ',', q())[$i],
$ms / (FACTORS)[$i];
$ms = $ms % (FACTORS)[$i];
}
return $str;
}
my $diff = 1000 * shift;
my $TIME_R = qr/[0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3}/;
while (<>) {
if (my ($from, $to) = /($TIME_R) --> ($TIME_R)/) {
my $i = 0;
for my $time ($from, $to) {
$time = time2ms($time) + $diff;
print ms2time($time), (' --> ', "n")[$i++];
}
} else {
print;
}
}
Thanks for the script! Let me add a small improvement though: In the ms2time loop, if $i==3, sprintf should be '%03d' instead of '%02d'.
– Vangelis Tasoulas
Jan 6 '14 at 20:07
@VangelisTasoulas: Updated.
– choroba
Feb 12 '17 at 17:11
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f96531%2fbash-script-shift-seconds%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Unless the subtitle file spans more than 24 hours, you can use date
for this:
#!/usr/bin/env bash
set -o errexit -o noclobber -o nounset -o pipefail
date_offset="$1"
shift_date() {
date --date="$1 $date_offset" +%T,%N | cut -c 1-12
}
while read -r line
do
if [[ $line =~ ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9] --> [0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9]$ ]]
then
read -r start_date separator end_date <<<"$line"
new_start_date="$(shift_date "$start_date")"
new_end_date="$(shift_date "$end_date")"
printf "%s %s %sn" "$new_start_date" "$separator" "$new_end_date"
echo "New date"
else
printf "%sn" "$line"
fi
done
For some reason you need to use decimal numbers with this, but it works:
$ ./shifter.sh "+3.0 seconds" < bmt.srt
5
00:01:05,323 --> 00:01:08,572
New date
Hello, my frieds!
6
add a comment |
Unless the subtitle file spans more than 24 hours, you can use date
for this:
#!/usr/bin/env bash
set -o errexit -o noclobber -o nounset -o pipefail
date_offset="$1"
shift_date() {
date --date="$1 $date_offset" +%T,%N | cut -c 1-12
}
while read -r line
do
if [[ $line =~ ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9] --> [0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9]$ ]]
then
read -r start_date separator end_date <<<"$line"
new_start_date="$(shift_date "$start_date")"
new_end_date="$(shift_date "$end_date")"
printf "%s %s %sn" "$new_start_date" "$separator" "$new_end_date"
echo "New date"
else
printf "%sn" "$line"
fi
done
For some reason you need to use decimal numbers with this, but it works:
$ ./shifter.sh "+3.0 seconds" < bmt.srt
5
00:01:05,323 --> 00:01:08,572
New date
Hello, my frieds!
6
add a comment |
Unless the subtitle file spans more than 24 hours, you can use date
for this:
#!/usr/bin/env bash
set -o errexit -o noclobber -o nounset -o pipefail
date_offset="$1"
shift_date() {
date --date="$1 $date_offset" +%T,%N | cut -c 1-12
}
while read -r line
do
if [[ $line =~ ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9] --> [0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9]$ ]]
then
read -r start_date separator end_date <<<"$line"
new_start_date="$(shift_date "$start_date")"
new_end_date="$(shift_date "$end_date")"
printf "%s %s %sn" "$new_start_date" "$separator" "$new_end_date"
echo "New date"
else
printf "%sn" "$line"
fi
done
For some reason you need to use decimal numbers with this, but it works:
$ ./shifter.sh "+3.0 seconds" < bmt.srt
5
00:01:05,323 --> 00:01:08,572
New date
Hello, my frieds!
6
Unless the subtitle file spans more than 24 hours, you can use date
for this:
#!/usr/bin/env bash
set -o errexit -o noclobber -o nounset -o pipefail
date_offset="$1"
shift_date() {
date --date="$1 $date_offset" +%T,%N | cut -c 1-12
}
while read -r line
do
if [[ $line =~ ^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9] --> [0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9]$ ]]
then
read -r start_date separator end_date <<<"$line"
new_start_date="$(shift_date "$start_date")"
new_end_date="$(shift_date "$end_date")"
printf "%s %s %sn" "$new_start_date" "$separator" "$new_end_date"
echo "New date"
else
printf "%sn" "$line"
fi
done
For some reason you need to use decimal numbers with this, but it works:
$ ./shifter.sh "+3.0 seconds" < bmt.srt
5
00:01:05,323 --> 00:01:08,572
New date
Hello, my frieds!
6
edited Oct 21 '13 at 7:25
answered Oct 17 '13 at 21:08
l0b0l0b0
28k17119246
28k17119246
add a comment |
add a comment |
Perl solution. I did not use any classical time handling module, as miliseconds handling is generally poorly supported.
#!/usr/bin/perl
use warnings;
use strict;
use constant FACTORS => (60 * 60 * 1000,
60 * 1000,
1000,
1);
sub time2ms {
my $time = shift;
my ($ms, $i) = (0, 0);
$ms += (FACTORS)[$i++] * $_ for split /[^0-9]/, $time;
return $ms;
}
sub ms2time {
my $ms = shift;
my $str = q();
for my $i (0 .. 3) {
$str .= sprintf +($i == 3 ? '%03d' : '%02d')
. (':', ':', ',', q())[$i],
$ms / (FACTORS)[$i];
$ms = $ms % (FACTORS)[$i];
}
return $str;
}
my $diff = 1000 * shift;
my $TIME_R = qr/[0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3}/;
while (<>) {
if (my ($from, $to) = /($TIME_R) --> ($TIME_R)/) {
my $i = 0;
for my $time ($from, $to) {
$time = time2ms($time) + $diff;
print ms2time($time), (' --> ', "n")[$i++];
}
} else {
print;
}
}
Thanks for the script! Let me add a small improvement though: In the ms2time loop, if $i==3, sprintf should be '%03d' instead of '%02d'.
– Vangelis Tasoulas
Jan 6 '14 at 20:07
@VangelisTasoulas: Updated.
– choroba
Feb 12 '17 at 17:11
add a comment |
Perl solution. I did not use any classical time handling module, as miliseconds handling is generally poorly supported.
#!/usr/bin/perl
use warnings;
use strict;
use constant FACTORS => (60 * 60 * 1000,
60 * 1000,
1000,
1);
sub time2ms {
my $time = shift;
my ($ms, $i) = (0, 0);
$ms += (FACTORS)[$i++] * $_ for split /[^0-9]/, $time;
return $ms;
}
sub ms2time {
my $ms = shift;
my $str = q();
for my $i (0 .. 3) {
$str .= sprintf +($i == 3 ? '%03d' : '%02d')
. (':', ':', ',', q())[$i],
$ms / (FACTORS)[$i];
$ms = $ms % (FACTORS)[$i];
}
return $str;
}
my $diff = 1000 * shift;
my $TIME_R = qr/[0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3}/;
while (<>) {
if (my ($from, $to) = /($TIME_R) --> ($TIME_R)/) {
my $i = 0;
for my $time ($from, $to) {
$time = time2ms($time) + $diff;
print ms2time($time), (' --> ', "n")[$i++];
}
} else {
print;
}
}
Thanks for the script! Let me add a small improvement though: In the ms2time loop, if $i==3, sprintf should be '%03d' instead of '%02d'.
– Vangelis Tasoulas
Jan 6 '14 at 20:07
@VangelisTasoulas: Updated.
– choroba
Feb 12 '17 at 17:11
add a comment |
Perl solution. I did not use any classical time handling module, as miliseconds handling is generally poorly supported.
#!/usr/bin/perl
use warnings;
use strict;
use constant FACTORS => (60 * 60 * 1000,
60 * 1000,
1000,
1);
sub time2ms {
my $time = shift;
my ($ms, $i) = (0, 0);
$ms += (FACTORS)[$i++] * $_ for split /[^0-9]/, $time;
return $ms;
}
sub ms2time {
my $ms = shift;
my $str = q();
for my $i (0 .. 3) {
$str .= sprintf +($i == 3 ? '%03d' : '%02d')
. (':', ':', ',', q())[$i],
$ms / (FACTORS)[$i];
$ms = $ms % (FACTORS)[$i];
}
return $str;
}
my $diff = 1000 * shift;
my $TIME_R = qr/[0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3}/;
while (<>) {
if (my ($from, $to) = /($TIME_R) --> ($TIME_R)/) {
my $i = 0;
for my $time ($from, $to) {
$time = time2ms($time) + $diff;
print ms2time($time), (' --> ', "n")[$i++];
}
} else {
print;
}
}
Perl solution. I did not use any classical time handling module, as miliseconds handling is generally poorly supported.
#!/usr/bin/perl
use warnings;
use strict;
use constant FACTORS => (60 * 60 * 1000,
60 * 1000,
1000,
1);
sub time2ms {
my $time = shift;
my ($ms, $i) = (0, 0);
$ms += (FACTORS)[$i++] * $_ for split /[^0-9]/, $time;
return $ms;
}
sub ms2time {
my $ms = shift;
my $str = q();
for my $i (0 .. 3) {
$str .= sprintf +($i == 3 ? '%03d' : '%02d')
. (':', ':', ',', q())[$i],
$ms / (FACTORS)[$i];
$ms = $ms % (FACTORS)[$i];
}
return $str;
}
my $diff = 1000 * shift;
my $TIME_R = qr/[0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3}/;
while (<>) {
if (my ($from, $to) = /($TIME_R) --> ($TIME_R)/) {
my $i = 0;
for my $time ($from, $to) {
$time = time2ms($time) + $diff;
print ms2time($time), (' --> ', "n")[$i++];
}
} else {
print;
}
}
edited Feb 12 '17 at 17:11
answered Oct 17 '13 at 22:31
chorobachoroba
26.5k44773
26.5k44773
Thanks for the script! Let me add a small improvement though: In the ms2time loop, if $i==3, sprintf should be '%03d' instead of '%02d'.
– Vangelis Tasoulas
Jan 6 '14 at 20:07
@VangelisTasoulas: Updated.
– choroba
Feb 12 '17 at 17:11
add a comment |
Thanks for the script! Let me add a small improvement though: In the ms2time loop, if $i==3, sprintf should be '%03d' instead of '%02d'.
– Vangelis Tasoulas
Jan 6 '14 at 20:07
@VangelisTasoulas: Updated.
– choroba
Feb 12 '17 at 17:11
Thanks for the script! Let me add a small improvement though: In the ms2time loop, if $i==3, sprintf should be '%03d' instead of '%02d'.
– Vangelis Tasoulas
Jan 6 '14 at 20:07
Thanks for the script! Let me add a small improvement though: In the ms2time loop, if $i==3, sprintf should be '%03d' instead of '%02d'.
– Vangelis Tasoulas
Jan 6 '14 at 20:07
@VangelisTasoulas: Updated.
– choroba
Feb 12 '17 at 17:11
@VangelisTasoulas: Updated.
– choroba
Feb 12 '17 at 17:11
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f96531%2fbash-script-shift-seconds%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
mplayer has some subtitle delay options, only I don't know if it can store it as new subtitle; still, I suspect there's an existing solution for this out there somewhere...
– frostschutz
Oct 17 '13 at 20:15