Dealing with space in file links using bash
I got a problem. Here is my bash script to merge videos with subs:
#!/bin/bash
cd /media/ptrknvk/'TOSHIBA EXT'/Shows/My/'Doctor Who'/
url0='DW s11e0'
url1='DW s11e'
for(( i=1; i<11; i++ ))
do
if ! [ $i -gt 9 ];
then
mkvmerge -o $url0$i.mkv $url0$i.mkv $url0$i.srt
rm $url0$i.srt
else
mkvmerge -o $url1$i.mkv $url1$i.mkv $url1$i.srt
rm $url1$i.srt
fi
done
File have names like for example "DW s11e05.mkv" and they actually exist in the directory.
And here is a result:
mkvmerge v8.8.0 ('Wind at my back') 64bit
Error: The file 's11e09.mkv' could not be opened for reading: open file error.
rm: cannot remove 'DW': No such file or directory
rm: cannot remove 's11e09.srt': No such file or directory
mkvmerge v8.8.0 ('Wind at my back') 64bit
Error: The file 's11e10.mkv' could not be opened for reading: open file error.
rm: cannot remove 'DW': No such file or directory
rm: cannot remove 's11e10.srt': No such file or directory
As you can see '' before a space doesn't work here. I also tried to use echo, but nothing changed (mb I've used it in a wrong way).
Sorry for my little bit nooby style.
bash scripts
add a comment |
I got a problem. Here is my bash script to merge videos with subs:
#!/bin/bash
cd /media/ptrknvk/'TOSHIBA EXT'/Shows/My/'Doctor Who'/
url0='DW s11e0'
url1='DW s11e'
for(( i=1; i<11; i++ ))
do
if ! [ $i -gt 9 ];
then
mkvmerge -o $url0$i.mkv $url0$i.mkv $url0$i.srt
rm $url0$i.srt
else
mkvmerge -o $url1$i.mkv $url1$i.mkv $url1$i.srt
rm $url1$i.srt
fi
done
File have names like for example "DW s11e05.mkv" and they actually exist in the directory.
And here is a result:
mkvmerge v8.8.0 ('Wind at my back') 64bit
Error: The file 's11e09.mkv' could not be opened for reading: open file error.
rm: cannot remove 'DW': No such file or directory
rm: cannot remove 's11e09.srt': No such file or directory
mkvmerge v8.8.0 ('Wind at my back') 64bit
Error: The file 's11e10.mkv' could not be opened for reading: open file error.
rm: cannot remove 'DW': No such file or directory
rm: cannot remove 's11e10.srt': No such file or directory
As you can see '' before a space doesn't work here. I also tried to use echo, but nothing changed (mb I've used it in a wrong way).
Sorry for my little bit nooby style.
bash scripts
add a comment |
I got a problem. Here is my bash script to merge videos with subs:
#!/bin/bash
cd /media/ptrknvk/'TOSHIBA EXT'/Shows/My/'Doctor Who'/
url0='DW s11e0'
url1='DW s11e'
for(( i=1; i<11; i++ ))
do
if ! [ $i -gt 9 ];
then
mkvmerge -o $url0$i.mkv $url0$i.mkv $url0$i.srt
rm $url0$i.srt
else
mkvmerge -o $url1$i.mkv $url1$i.mkv $url1$i.srt
rm $url1$i.srt
fi
done
File have names like for example "DW s11e05.mkv" and they actually exist in the directory.
And here is a result:
mkvmerge v8.8.0 ('Wind at my back') 64bit
Error: The file 's11e09.mkv' could not be opened for reading: open file error.
rm: cannot remove 'DW': No such file or directory
rm: cannot remove 's11e09.srt': No such file or directory
mkvmerge v8.8.0 ('Wind at my back') 64bit
Error: The file 's11e10.mkv' could not be opened for reading: open file error.
rm: cannot remove 'DW': No such file or directory
rm: cannot remove 's11e10.srt': No such file or directory
As you can see '' before a space doesn't work here. I also tried to use echo, but nothing changed (mb I've used it in a wrong way).
Sorry for my little bit nooby style.
bash scripts
I got a problem. Here is my bash script to merge videos with subs:
#!/bin/bash
cd /media/ptrknvk/'TOSHIBA EXT'/Shows/My/'Doctor Who'/
url0='DW s11e0'
url1='DW s11e'
for(( i=1; i<11; i++ ))
do
if ! [ $i -gt 9 ];
then
mkvmerge -o $url0$i.mkv $url0$i.mkv $url0$i.srt
rm $url0$i.srt
else
mkvmerge -o $url1$i.mkv $url1$i.mkv $url1$i.srt
rm $url1$i.srt
fi
done
File have names like for example "DW s11e05.mkv" and they actually exist in the directory.
And here is a result:
mkvmerge v8.8.0 ('Wind at my back') 64bit
Error: The file 's11e09.mkv' could not be opened for reading: open file error.
rm: cannot remove 'DW': No such file or directory
rm: cannot remove 's11e09.srt': No such file or directory
mkvmerge v8.8.0 ('Wind at my back') 64bit
Error: The file 's11e10.mkv' could not be opened for reading: open file error.
rm: cannot remove 'DW': No such file or directory
rm: cannot remove 's11e10.srt': No such file or directory
As you can see '' before a space doesn't work here. I also tried to use echo, but nothing changed (mb I've used it in a wrong way).
Sorry for my little bit nooby style.
bash scripts
bash scripts
asked 1 hour ago
Patrik Novák
157
157
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
You need to quote your variables. This should do what you want:
#!/bin/bash
cd /media/ptrknvk/'TOSHIBA EXT'/Shows/My/'Doctor Who'/
url0='DW s11e0'
url1='DW s11e'
for(( i=1; i<11; i++ ))
do
if ! [ $i -gt 9 ];
then
mkvmerge -o "$url0$i.mkv" "$url0$i.mkv" "$url0$i.srt" &&
rm "$url0$i.srt"
else
mkvmerge -o "$url1$i.mkv" "$url1$i.mkv" "$url1$i.srt" &&
rm "$url1$i.srt"
fi
done
Note that I also added a &&
after each mkvmerge
command so the rm
only runs if the mkvmerge
was successful. You don't want to delete the subtitle file if the merge failed!
That said, although there's absolutely nothing wrong with your approach, I feel you could make it considerable simpler and more elegant using shell globbing instead:
#!/bin/bash
for file in "/media/ptrknvk/TOSHIBA EXT/Shows/My/Doctor Who/"DW*mkv; do
srtFile=${file//.mkv/.srt}
mkvmerge -o "$file" "$file" "$srtFile" && rm "$srtFile"
done
You don't even need a script for this. You can just run it directly in the terminal as a one liner:
for file in "/media/ptrknvk/TOSHIBA EXT/Shows/My/Doctor Who/"DW*mkv; do
mkvmerge -o "$file" "$file" "${file//.mkv/.srt}" && rm "${file//.mkv/.srt}";
done
add a comment |
Quote variables to prevent word-splitting. By the way, double-quotes on a whole string is the preferred style.
#!/bin/bash
# Also exit if this fails
cd "/media/ptrknvk/TOSHIBA EXT/Shows/My/Doctor Who/" || exit
url0="DW s11e0"
url1="DW s11e"
for (( i=1; i<11; i++ )); do
# Also why use "not greater-than" when "less-than-or-equal" exists?
if [ $i -le 9 ]; then
# Also you can DRY* out this part with variables.
url="$url0"
else
url="$url1"
fi
# Also when concatenating variables, it's clearer to use the "${var}" style. **
f_mkv="${url}${i}.mkv"
f_srt="${url}${i}.srt"
mkvmerge -o "$f_mkv" "$f_mkv" "$f_srt"
rm "$f_srt"
done
Shellcheck is really useful for finding problems like this in shell scripts.
* DRY = Don't Repeat Yourself
** Or you could use printf -v
, but it's not a big improvement in this case. For example
printf -v f_mkv "%s%s.mkv" "$url" $i
2
You may also wanna mention that using${varname}
style is better in cases where you are concatenating string with variable, so that the shell clearly knows what part of the token is a variable
– Sergiy Kolodyazhnyy
1 hour ago
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "89"
};
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: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
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%2faskubuntu.com%2fquestions%2f1106116%2fdealing-with-space-in-file-links-using-bash%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
You need to quote your variables. This should do what you want:
#!/bin/bash
cd /media/ptrknvk/'TOSHIBA EXT'/Shows/My/'Doctor Who'/
url0='DW s11e0'
url1='DW s11e'
for(( i=1; i<11; i++ ))
do
if ! [ $i -gt 9 ];
then
mkvmerge -o "$url0$i.mkv" "$url0$i.mkv" "$url0$i.srt" &&
rm "$url0$i.srt"
else
mkvmerge -o "$url1$i.mkv" "$url1$i.mkv" "$url1$i.srt" &&
rm "$url1$i.srt"
fi
done
Note that I also added a &&
after each mkvmerge
command so the rm
only runs if the mkvmerge
was successful. You don't want to delete the subtitle file if the merge failed!
That said, although there's absolutely nothing wrong with your approach, I feel you could make it considerable simpler and more elegant using shell globbing instead:
#!/bin/bash
for file in "/media/ptrknvk/TOSHIBA EXT/Shows/My/Doctor Who/"DW*mkv; do
srtFile=${file//.mkv/.srt}
mkvmerge -o "$file" "$file" "$srtFile" && rm "$srtFile"
done
You don't even need a script for this. You can just run it directly in the terminal as a one liner:
for file in "/media/ptrknvk/TOSHIBA EXT/Shows/My/Doctor Who/"DW*mkv; do
mkvmerge -o "$file" "$file" "${file//.mkv/.srt}" && rm "${file//.mkv/.srt}";
done
add a comment |
You need to quote your variables. This should do what you want:
#!/bin/bash
cd /media/ptrknvk/'TOSHIBA EXT'/Shows/My/'Doctor Who'/
url0='DW s11e0'
url1='DW s11e'
for(( i=1; i<11; i++ ))
do
if ! [ $i -gt 9 ];
then
mkvmerge -o "$url0$i.mkv" "$url0$i.mkv" "$url0$i.srt" &&
rm "$url0$i.srt"
else
mkvmerge -o "$url1$i.mkv" "$url1$i.mkv" "$url1$i.srt" &&
rm "$url1$i.srt"
fi
done
Note that I also added a &&
after each mkvmerge
command so the rm
only runs if the mkvmerge
was successful. You don't want to delete the subtitle file if the merge failed!
That said, although there's absolutely nothing wrong with your approach, I feel you could make it considerable simpler and more elegant using shell globbing instead:
#!/bin/bash
for file in "/media/ptrknvk/TOSHIBA EXT/Shows/My/Doctor Who/"DW*mkv; do
srtFile=${file//.mkv/.srt}
mkvmerge -o "$file" "$file" "$srtFile" && rm "$srtFile"
done
You don't even need a script for this. You can just run it directly in the terminal as a one liner:
for file in "/media/ptrknvk/TOSHIBA EXT/Shows/My/Doctor Who/"DW*mkv; do
mkvmerge -o "$file" "$file" "${file//.mkv/.srt}" && rm "${file//.mkv/.srt}";
done
add a comment |
You need to quote your variables. This should do what you want:
#!/bin/bash
cd /media/ptrknvk/'TOSHIBA EXT'/Shows/My/'Doctor Who'/
url0='DW s11e0'
url1='DW s11e'
for(( i=1; i<11; i++ ))
do
if ! [ $i -gt 9 ];
then
mkvmerge -o "$url0$i.mkv" "$url0$i.mkv" "$url0$i.srt" &&
rm "$url0$i.srt"
else
mkvmerge -o "$url1$i.mkv" "$url1$i.mkv" "$url1$i.srt" &&
rm "$url1$i.srt"
fi
done
Note that I also added a &&
after each mkvmerge
command so the rm
only runs if the mkvmerge
was successful. You don't want to delete the subtitle file if the merge failed!
That said, although there's absolutely nothing wrong with your approach, I feel you could make it considerable simpler and more elegant using shell globbing instead:
#!/bin/bash
for file in "/media/ptrknvk/TOSHIBA EXT/Shows/My/Doctor Who/"DW*mkv; do
srtFile=${file//.mkv/.srt}
mkvmerge -o "$file" "$file" "$srtFile" && rm "$srtFile"
done
You don't even need a script for this. You can just run it directly in the terminal as a one liner:
for file in "/media/ptrknvk/TOSHIBA EXT/Shows/My/Doctor Who/"DW*mkv; do
mkvmerge -o "$file" "$file" "${file//.mkv/.srt}" && rm "${file//.mkv/.srt}";
done
You need to quote your variables. This should do what you want:
#!/bin/bash
cd /media/ptrknvk/'TOSHIBA EXT'/Shows/My/'Doctor Who'/
url0='DW s11e0'
url1='DW s11e'
for(( i=1; i<11; i++ ))
do
if ! [ $i -gt 9 ];
then
mkvmerge -o "$url0$i.mkv" "$url0$i.mkv" "$url0$i.srt" &&
rm "$url0$i.srt"
else
mkvmerge -o "$url1$i.mkv" "$url1$i.mkv" "$url1$i.srt" &&
rm "$url1$i.srt"
fi
done
Note that I also added a &&
after each mkvmerge
command so the rm
only runs if the mkvmerge
was successful. You don't want to delete the subtitle file if the merge failed!
That said, although there's absolutely nothing wrong with your approach, I feel you could make it considerable simpler and more elegant using shell globbing instead:
#!/bin/bash
for file in "/media/ptrknvk/TOSHIBA EXT/Shows/My/Doctor Who/"DW*mkv; do
srtFile=${file//.mkv/.srt}
mkvmerge -o "$file" "$file" "$srtFile" && rm "$srtFile"
done
You don't even need a script for this. You can just run it directly in the terminal as a one liner:
for file in "/media/ptrknvk/TOSHIBA EXT/Shows/My/Doctor Who/"DW*mkv; do
mkvmerge -o "$file" "$file" "${file//.mkv/.srt}" && rm "${file//.mkv/.srt}";
done
edited 1 hour ago
answered 1 hour ago
terdon♦
64.3k12136212
64.3k12136212
add a comment |
add a comment |
Quote variables to prevent word-splitting. By the way, double-quotes on a whole string is the preferred style.
#!/bin/bash
# Also exit if this fails
cd "/media/ptrknvk/TOSHIBA EXT/Shows/My/Doctor Who/" || exit
url0="DW s11e0"
url1="DW s11e"
for (( i=1; i<11; i++ )); do
# Also why use "not greater-than" when "less-than-or-equal" exists?
if [ $i -le 9 ]; then
# Also you can DRY* out this part with variables.
url="$url0"
else
url="$url1"
fi
# Also when concatenating variables, it's clearer to use the "${var}" style. **
f_mkv="${url}${i}.mkv"
f_srt="${url}${i}.srt"
mkvmerge -o "$f_mkv" "$f_mkv" "$f_srt"
rm "$f_srt"
done
Shellcheck is really useful for finding problems like this in shell scripts.
* DRY = Don't Repeat Yourself
** Or you could use printf -v
, but it's not a big improvement in this case. For example
printf -v f_mkv "%s%s.mkv" "$url" $i
2
You may also wanna mention that using${varname}
style is better in cases where you are concatenating string with variable, so that the shell clearly knows what part of the token is a variable
– Sergiy Kolodyazhnyy
1 hour ago
add a comment |
Quote variables to prevent word-splitting. By the way, double-quotes on a whole string is the preferred style.
#!/bin/bash
# Also exit if this fails
cd "/media/ptrknvk/TOSHIBA EXT/Shows/My/Doctor Who/" || exit
url0="DW s11e0"
url1="DW s11e"
for (( i=1; i<11; i++ )); do
# Also why use "not greater-than" when "less-than-or-equal" exists?
if [ $i -le 9 ]; then
# Also you can DRY* out this part with variables.
url="$url0"
else
url="$url1"
fi
# Also when concatenating variables, it's clearer to use the "${var}" style. **
f_mkv="${url}${i}.mkv"
f_srt="${url}${i}.srt"
mkvmerge -o "$f_mkv" "$f_mkv" "$f_srt"
rm "$f_srt"
done
Shellcheck is really useful for finding problems like this in shell scripts.
* DRY = Don't Repeat Yourself
** Or you could use printf -v
, but it's not a big improvement in this case. For example
printf -v f_mkv "%s%s.mkv" "$url" $i
2
You may also wanna mention that using${varname}
style is better in cases where you are concatenating string with variable, so that the shell clearly knows what part of the token is a variable
– Sergiy Kolodyazhnyy
1 hour ago
add a comment |
Quote variables to prevent word-splitting. By the way, double-quotes on a whole string is the preferred style.
#!/bin/bash
# Also exit if this fails
cd "/media/ptrknvk/TOSHIBA EXT/Shows/My/Doctor Who/" || exit
url0="DW s11e0"
url1="DW s11e"
for (( i=1; i<11; i++ )); do
# Also why use "not greater-than" when "less-than-or-equal" exists?
if [ $i -le 9 ]; then
# Also you can DRY* out this part with variables.
url="$url0"
else
url="$url1"
fi
# Also when concatenating variables, it's clearer to use the "${var}" style. **
f_mkv="${url}${i}.mkv"
f_srt="${url}${i}.srt"
mkvmerge -o "$f_mkv" "$f_mkv" "$f_srt"
rm "$f_srt"
done
Shellcheck is really useful for finding problems like this in shell scripts.
* DRY = Don't Repeat Yourself
** Or you could use printf -v
, but it's not a big improvement in this case. For example
printf -v f_mkv "%s%s.mkv" "$url" $i
Quote variables to prevent word-splitting. By the way, double-quotes on a whole string is the preferred style.
#!/bin/bash
# Also exit if this fails
cd "/media/ptrknvk/TOSHIBA EXT/Shows/My/Doctor Who/" || exit
url0="DW s11e0"
url1="DW s11e"
for (( i=1; i<11; i++ )); do
# Also why use "not greater-than" when "less-than-or-equal" exists?
if [ $i -le 9 ]; then
# Also you can DRY* out this part with variables.
url="$url0"
else
url="$url1"
fi
# Also when concatenating variables, it's clearer to use the "${var}" style. **
f_mkv="${url}${i}.mkv"
f_srt="${url}${i}.srt"
mkvmerge -o "$f_mkv" "$f_mkv" "$f_srt"
rm "$f_srt"
done
Shellcheck is really useful for finding problems like this in shell scripts.
* DRY = Don't Repeat Yourself
** Or you could use printf -v
, but it's not a big improvement in this case. For example
printf -v f_mkv "%s%s.mkv" "$url" $i
edited 40 mins ago
answered 1 hour ago
wjandrea
8,35842259
8,35842259
2
You may also wanna mention that using${varname}
style is better in cases where you are concatenating string with variable, so that the shell clearly knows what part of the token is a variable
– Sergiy Kolodyazhnyy
1 hour ago
add a comment |
2
You may also wanna mention that using${varname}
style is better in cases where you are concatenating string with variable, so that the shell clearly knows what part of the token is a variable
– Sergiy Kolodyazhnyy
1 hour ago
2
2
You may also wanna mention that using
${varname}
style is better in cases where you are concatenating string with variable, so that the shell clearly knows what part of the token is a variable– Sergiy Kolodyazhnyy
1 hour ago
You may also wanna mention that using
${varname}
style is better in cases where you are concatenating string with variable, so that the shell clearly knows what part of the token is a variable– Sergiy Kolodyazhnyy
1 hour ago
add a comment |
Thanks for contributing an answer to Ask Ubuntu!
- 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.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- 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%2faskubuntu.com%2fquestions%2f1106116%2fdealing-with-space-in-file-links-using-bash%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