Find fails if filename contains brackets












2















I'm trying to use find inside a loop to create a variable that contains a file matching the filename + desired string



Example:



file1.en.srt
file1.mkv
file1.pt.srt


This is the relevant part of the code:



shopt -s nullglob
shopt -s nocaseglob

if [ -d "$1" ]; then
for file in "${1%/}/"*mkv; do
# Get filename to match against subs and audios
filename="$(basename "$file" .mkv)"

# Find matching subtitle file
engsubs="$(find . -name "$filename*en.srt*" | sed -e 's,^./,,')"

# Find matching audio file
engaudio="$(find . -iname "$filename*en.ac3" -o -iname "$filename*en.eac3" -o -iname "$filename*en.dts" | sed -e 's,^./,,')"
done
fi


It works if files don't contain brackets, but the find commands don't find anything for files whose names contain brackets. Why this is happening? I want to create a variable like $en that would contain file1.en.srt










share|improve this question




















  • 5





    Please don't just tell us "it works" and "it doesn't work". How does it fail? What error message do you get? Which part of it fails? How do you call this script? What is $1?

    – terdon
    yesterday











  • No error message, it just won't find anything if the filenames contains brackets ... I call this script from command line... $1 would be the path

    – Freedo
    yesterday








  • 1





    please try to create a minimal code example for us to reproduce without your whole script.

    – RoVo
    yesterday








  • 1





    Related: Why is looping over find's output bad practice?

    – Kusalananda
    yesterday











  • Also related: Why does my shell script choke on whitespace or other special characters?

    – Kusalananda
    yesterday
















2















I'm trying to use find inside a loop to create a variable that contains a file matching the filename + desired string



Example:



file1.en.srt
file1.mkv
file1.pt.srt


This is the relevant part of the code:



shopt -s nullglob
shopt -s nocaseglob

if [ -d "$1" ]; then
for file in "${1%/}/"*mkv; do
# Get filename to match against subs and audios
filename="$(basename "$file" .mkv)"

# Find matching subtitle file
engsubs="$(find . -name "$filename*en.srt*" | sed -e 's,^./,,')"

# Find matching audio file
engaudio="$(find . -iname "$filename*en.ac3" -o -iname "$filename*en.eac3" -o -iname "$filename*en.dts" | sed -e 's,^./,,')"
done
fi


It works if files don't contain brackets, but the find commands don't find anything for files whose names contain brackets. Why this is happening? I want to create a variable like $en that would contain file1.en.srt










share|improve this question




















  • 5





    Please don't just tell us "it works" and "it doesn't work". How does it fail? What error message do you get? Which part of it fails? How do you call this script? What is $1?

    – terdon
    yesterday











  • No error message, it just won't find anything if the filenames contains brackets ... I call this script from command line... $1 would be the path

    – Freedo
    yesterday








  • 1





    please try to create a minimal code example for us to reproduce without your whole script.

    – RoVo
    yesterday








  • 1





    Related: Why is looping over find's output bad practice?

    – Kusalananda
    yesterday











  • Also related: Why does my shell script choke on whitespace or other special characters?

    – Kusalananda
    yesterday














2












2








2








I'm trying to use find inside a loop to create a variable that contains a file matching the filename + desired string



Example:



file1.en.srt
file1.mkv
file1.pt.srt


This is the relevant part of the code:



shopt -s nullglob
shopt -s nocaseglob

if [ -d "$1" ]; then
for file in "${1%/}/"*mkv; do
# Get filename to match against subs and audios
filename="$(basename "$file" .mkv)"

# Find matching subtitle file
engsubs="$(find . -name "$filename*en.srt*" | sed -e 's,^./,,')"

# Find matching audio file
engaudio="$(find . -iname "$filename*en.ac3" -o -iname "$filename*en.eac3" -o -iname "$filename*en.dts" | sed -e 's,^./,,')"
done
fi


It works if files don't contain brackets, but the find commands don't find anything for files whose names contain brackets. Why this is happening? I want to create a variable like $en that would contain file1.en.srt










share|improve this question
















I'm trying to use find inside a loop to create a variable that contains a file matching the filename + desired string



Example:



file1.en.srt
file1.mkv
file1.pt.srt


This is the relevant part of the code:



shopt -s nullglob
shopt -s nocaseglob

if [ -d "$1" ]; then
for file in "${1%/}/"*mkv; do
# Get filename to match against subs and audios
filename="$(basename "$file" .mkv)"

# Find matching subtitle file
engsubs="$(find . -name "$filename*en.srt*" | sed -e 's,^./,,')"

# Find matching audio file
engaudio="$(find . -iname "$filename*en.ac3" -o -iname "$filename*en.eac3" -o -iname "$filename*en.dts" | sed -e 's,^./,,')"
done
fi


It works if files don't contain brackets, but the find commands don't find anything for files whose names contain brackets. Why this is happening? I want to create a variable like $en that would contain file1.en.srt







bash shell-script find filenames






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited yesterday









wjandrea

504413




504413










asked yesterday









FreedoFreedo

450520




450520








  • 5





    Please don't just tell us "it works" and "it doesn't work". How does it fail? What error message do you get? Which part of it fails? How do you call this script? What is $1?

    – terdon
    yesterday











  • No error message, it just won't find anything if the filenames contains brackets ... I call this script from command line... $1 would be the path

    – Freedo
    yesterday








  • 1





    please try to create a minimal code example for us to reproduce without your whole script.

    – RoVo
    yesterday








  • 1





    Related: Why is looping over find's output bad practice?

    – Kusalananda
    yesterday











  • Also related: Why does my shell script choke on whitespace or other special characters?

    – Kusalananda
    yesterday














  • 5





    Please don't just tell us "it works" and "it doesn't work". How does it fail? What error message do you get? Which part of it fails? How do you call this script? What is $1?

    – terdon
    yesterday











  • No error message, it just won't find anything if the filenames contains brackets ... I call this script from command line... $1 would be the path

    – Freedo
    yesterday








  • 1





    please try to create a minimal code example for us to reproduce without your whole script.

    – RoVo
    yesterday








  • 1





    Related: Why is looping over find's output bad practice?

    – Kusalananda
    yesterday











  • Also related: Why does my shell script choke on whitespace or other special characters?

    – Kusalananda
    yesterday








5




5





Please don't just tell us "it works" and "it doesn't work". How does it fail? What error message do you get? Which part of it fails? How do you call this script? What is $1?

– terdon
yesterday





Please don't just tell us "it works" and "it doesn't work". How does it fail? What error message do you get? Which part of it fails? How do you call this script? What is $1?

– terdon
yesterday













No error message, it just won't find anything if the filenames contains brackets ... I call this script from command line... $1 would be the path

– Freedo
yesterday







No error message, it just won't find anything if the filenames contains brackets ... I call this script from command line... $1 would be the path

– Freedo
yesterday






1




1





please try to create a minimal code example for us to reproduce without your whole script.

– RoVo
yesterday







please try to create a minimal code example for us to reproduce without your whole script.

– RoVo
yesterday






1




1





Related: Why is looping over find's output bad practice?

– Kusalananda
yesterday





Related: Why is looping over find's output bad practice?

– Kusalananda
yesterday













Also related: Why does my shell script choke on whitespace or other special characters?

– Kusalananda
yesterday





Also related: Why does my shell script choke on whitespace or other special characters?

– Kusalananda
yesterday










1 Answer
1






active

oldest

votes


















8














The problem is that [ and ] are glob characters. For example, consider this file:



ba[r].mkv


When running your script on that file, $filename will be: ba[r] and therefore your find command will be:



find . -name 'ba[r]*pt-BR.srt*'


Since [r] is a single letter character class, it means r. So your command is looking for a filename starting with ba, then an r, then any character(s), and pt-BR.srt and any characters again. You need to escape the brackets:



find . -name 'ba[r]*pt-BR.srt*'


The simplest way to do that is to use printf and %q. So just change this line:



filename="$(basename "$file" .mkv)"


To this:



filename=$(printf '%q' "$(basename "$file" .mkv)")





share|improve this answer
























  • Yeah I just noticed now that I didn't need that * at the end of srt or other file extensions lol. And it worked...thanks so much <3. Do you think this could mess with other filenames containing space, (), ç or other special characters?

    – Freedo
    yesterday






  • 1





    @Freedo no, the spaces and ( will also be escaped. Try running printf '%qn' "a ho[r]i(b)le file".

    – terdon
    yesterday











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
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f508462%2ffind-fails-if-filename-contains-brackets%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









8














The problem is that [ and ] are glob characters. For example, consider this file:



ba[r].mkv


When running your script on that file, $filename will be: ba[r] and therefore your find command will be:



find . -name 'ba[r]*pt-BR.srt*'


Since [r] is a single letter character class, it means r. So your command is looking for a filename starting with ba, then an r, then any character(s), and pt-BR.srt and any characters again. You need to escape the brackets:



find . -name 'ba[r]*pt-BR.srt*'


The simplest way to do that is to use printf and %q. So just change this line:



filename="$(basename "$file" .mkv)"


To this:



filename=$(printf '%q' "$(basename "$file" .mkv)")





share|improve this answer
























  • Yeah I just noticed now that I didn't need that * at the end of srt or other file extensions lol. And it worked...thanks so much <3. Do you think this could mess with other filenames containing space, (), ç or other special characters?

    – Freedo
    yesterday






  • 1





    @Freedo no, the spaces and ( will also be escaped. Try running printf '%qn' "a ho[r]i(b)le file".

    – terdon
    yesterday
















8














The problem is that [ and ] are glob characters. For example, consider this file:



ba[r].mkv


When running your script on that file, $filename will be: ba[r] and therefore your find command will be:



find . -name 'ba[r]*pt-BR.srt*'


Since [r] is a single letter character class, it means r. So your command is looking for a filename starting with ba, then an r, then any character(s), and pt-BR.srt and any characters again. You need to escape the brackets:



find . -name 'ba[r]*pt-BR.srt*'


The simplest way to do that is to use printf and %q. So just change this line:



filename="$(basename "$file" .mkv)"


To this:



filename=$(printf '%q' "$(basename "$file" .mkv)")





share|improve this answer
























  • Yeah I just noticed now that I didn't need that * at the end of srt or other file extensions lol. And it worked...thanks so much <3. Do you think this could mess with other filenames containing space, (), ç or other special characters?

    – Freedo
    yesterday






  • 1





    @Freedo no, the spaces and ( will also be escaped. Try running printf '%qn' "a ho[r]i(b)le file".

    – terdon
    yesterday














8












8








8







The problem is that [ and ] are glob characters. For example, consider this file:



ba[r].mkv


When running your script on that file, $filename will be: ba[r] and therefore your find command will be:



find . -name 'ba[r]*pt-BR.srt*'


Since [r] is a single letter character class, it means r. So your command is looking for a filename starting with ba, then an r, then any character(s), and pt-BR.srt and any characters again. You need to escape the brackets:



find . -name 'ba[r]*pt-BR.srt*'


The simplest way to do that is to use printf and %q. So just change this line:



filename="$(basename "$file" .mkv)"


To this:



filename=$(printf '%q' "$(basename "$file" .mkv)")





share|improve this answer













The problem is that [ and ] are glob characters. For example, consider this file:



ba[r].mkv


When running your script on that file, $filename will be: ba[r] and therefore your find command will be:



find . -name 'ba[r]*pt-BR.srt*'


Since [r] is a single letter character class, it means r. So your command is looking for a filename starting with ba, then an r, then any character(s), and pt-BR.srt and any characters again. You need to escape the brackets:



find . -name 'ba[r]*pt-BR.srt*'


The simplest way to do that is to use printf and %q. So just change this line:



filename="$(basename "$file" .mkv)"


To this:



filename=$(printf '%q' "$(basename "$file" .mkv)")






share|improve this answer












share|improve this answer



share|improve this answer










answered yesterday









terdonterdon

133k32264444




133k32264444













  • Yeah I just noticed now that I didn't need that * at the end of srt or other file extensions lol. And it worked...thanks so much <3. Do you think this could mess with other filenames containing space, (), ç or other special characters?

    – Freedo
    yesterday






  • 1





    @Freedo no, the spaces and ( will also be escaped. Try running printf '%qn' "a ho[r]i(b)le file".

    – terdon
    yesterday



















  • Yeah I just noticed now that I didn't need that * at the end of srt or other file extensions lol. And it worked...thanks so much <3. Do you think this could mess with other filenames containing space, (), ç or other special characters?

    – Freedo
    yesterday






  • 1





    @Freedo no, the spaces and ( will also be escaped. Try running printf '%qn' "a ho[r]i(b)le file".

    – terdon
    yesterday

















Yeah I just noticed now that I didn't need that * at the end of srt or other file extensions lol. And it worked...thanks so much <3. Do you think this could mess with other filenames containing space, (), ç or other special characters?

– Freedo
yesterday





Yeah I just noticed now that I didn't need that * at the end of srt or other file extensions lol. And it worked...thanks so much <3. Do you think this could mess with other filenames containing space, (), ç or other special characters?

– Freedo
yesterday




1




1





@Freedo no, the spaces and ( will also be escaped. Try running printf '%qn' "a ho[r]i(b)le file".

– terdon
yesterday





@Freedo no, the spaces and ( will also be escaped. Try running printf '%qn' "a ho[r]i(b)le file".

– terdon
yesterday


















draft saved

draft discarded




















































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.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f508462%2ffind-fails-if-filename-contains-brackets%23new-answer', 'question_page');
}
);

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







Popular posts from this blog

He _____ here since 1970 . Answer needed [closed]What does “since he was so high” mean?Meaning of “catch birds for”?How do I ensure “since” takes the meaning I want?“Who cares here” meaningWhat does “right round toward” mean?the time tense (had now been detected)What does the phrase “ring around the roses” mean here?Correct usage of “visited upon”Meaning of “foiled rail sabotage bid”It was the third time I had gone to Rome or It is the third time I had been to Rome

Bunad

Færeyskur hestur Heimild | Tengill | Tilvísanir | LeiðsagnarvalRossið - síða um færeyska hrossið á færeyskuGott ár hjá færeyska hestinum