Combining if/else with variables in find command in bash script

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
0
down vote

favorite












I am writing a script that prompts for user inputs and then runs a find command.



What I have works, but it feels like I have a lot of duplicated code due to the if / else structure. Is it possible to have inline if statement?



So, instead of this kind of thing:



if [[ $depth_boolean == y ]] || [[ $depth_boolean == yes ]]
then
if [[ $symlink_boolean == y ]] || [[ $symlink_boolean == yes ]]
then
find -L $location -maxdepth $depth -readable -iname "$query" -$find_type $find_type_option -$find_action
else
find $location -maxdepth $depth -readable -iname "$query" -$find_type $find_type_option -$find_action
fi
else
if [[ $symlink_boolean == y ]] || [[ $symlink_boolean == yes ]]
then
find -L $location -readable -iname "$query" -$find_type $find_type_option -$find_action
else
find $location -readable -iname "$query" -$find_type $find_type_option -$find_action
fi
fi


Is it possible to do something like this?



find if [ $symlink_boolean == y ]; then echo "-L";
fi $location if [ $symlink_boolean == y ]; then
echo "-maxdepth $depth"; fi -readable -iname "$query"
-$find_type $find_type_option -$find_action


The above doesn't work, but wondering if it is possible?










share|improve this question























  • Related - How can I expand a quoted variable to nothing if it's empty?
    – roaima
    Nov 18 at 9:20










  • Related: But what if …?
    – Scott
    Nov 18 at 9:42














up vote
0
down vote

favorite












I am writing a script that prompts for user inputs and then runs a find command.



What I have works, but it feels like I have a lot of duplicated code due to the if / else structure. Is it possible to have inline if statement?



So, instead of this kind of thing:



if [[ $depth_boolean == y ]] || [[ $depth_boolean == yes ]]
then
if [[ $symlink_boolean == y ]] || [[ $symlink_boolean == yes ]]
then
find -L $location -maxdepth $depth -readable -iname "$query" -$find_type $find_type_option -$find_action
else
find $location -maxdepth $depth -readable -iname "$query" -$find_type $find_type_option -$find_action
fi
else
if [[ $symlink_boolean == y ]] || [[ $symlink_boolean == yes ]]
then
find -L $location -readable -iname "$query" -$find_type $find_type_option -$find_action
else
find $location -readable -iname "$query" -$find_type $find_type_option -$find_action
fi
fi


Is it possible to do something like this?



find if [ $symlink_boolean == y ]; then echo "-L";
fi $location if [ $symlink_boolean == y ]; then
echo "-maxdepth $depth"; fi -readable -iname "$query"
-$find_type $find_type_option -$find_action


The above doesn't work, but wondering if it is possible?










share|improve this question























  • Related - How can I expand a quoted variable to nothing if it's empty?
    – roaima
    Nov 18 at 9:20










  • Related: But what if …?
    – Scott
    Nov 18 at 9:42












up vote
0
down vote

favorite









up vote
0
down vote

favorite











I am writing a script that prompts for user inputs and then runs a find command.



What I have works, but it feels like I have a lot of duplicated code due to the if / else structure. Is it possible to have inline if statement?



So, instead of this kind of thing:



if [[ $depth_boolean == y ]] || [[ $depth_boolean == yes ]]
then
if [[ $symlink_boolean == y ]] || [[ $symlink_boolean == yes ]]
then
find -L $location -maxdepth $depth -readable -iname "$query" -$find_type $find_type_option -$find_action
else
find $location -maxdepth $depth -readable -iname "$query" -$find_type $find_type_option -$find_action
fi
else
if [[ $symlink_boolean == y ]] || [[ $symlink_boolean == yes ]]
then
find -L $location -readable -iname "$query" -$find_type $find_type_option -$find_action
else
find $location -readable -iname "$query" -$find_type $find_type_option -$find_action
fi
fi


Is it possible to do something like this?



find if [ $symlink_boolean == y ]; then echo "-L";
fi $location if [ $symlink_boolean == y ]; then
echo "-maxdepth $depth"; fi -readable -iname "$query"
-$find_type $find_type_option -$find_action


The above doesn't work, but wondering if it is possible?










share|improve this question















I am writing a script that prompts for user inputs and then runs a find command.



What I have works, but it feels like I have a lot of duplicated code due to the if / else structure. Is it possible to have inline if statement?



So, instead of this kind of thing:



if [[ $depth_boolean == y ]] || [[ $depth_boolean == yes ]]
then
if [[ $symlink_boolean == y ]] || [[ $symlink_boolean == yes ]]
then
find -L $location -maxdepth $depth -readable -iname "$query" -$find_type $find_type_option -$find_action
else
find $location -maxdepth $depth -readable -iname "$query" -$find_type $find_type_option -$find_action
fi
else
if [[ $symlink_boolean == y ]] || [[ $symlink_boolean == yes ]]
then
find -L $location -readable -iname "$query" -$find_type $find_type_option -$find_action
else
find $location -readable -iname "$query" -$find_type $find_type_option -$find_action
fi
fi


Is it possible to do something like this?



find if [ $symlink_boolean == y ]; then echo "-L";
fi $location if [ $symlink_boolean == y ]; then
echo "-maxdepth $depth"; fi -readable -iname "$query"
-$find_type $find_type_option -$find_action


The above doesn't work, but wondering if it is possible?







bash find






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 18 at 9:30









ilkkachu

53.8k781146




53.8k781146










asked Nov 18 at 9:17









kerrin

1034




1034











  • Related - How can I expand a quoted variable to nothing if it's empty?
    – roaima
    Nov 18 at 9:20










  • Related: But what if …?
    – Scott
    Nov 18 at 9:42
















  • Related - How can I expand a quoted variable to nothing if it's empty?
    – roaima
    Nov 18 at 9:20










  • Related: But what if …?
    – Scott
    Nov 18 at 9:42















Related - How can I expand a quoted variable to nothing if it's empty?
– roaima
Nov 18 at 9:20




Related - How can I expand a quoted variable to nothing if it's empty?
– roaima
Nov 18 at 9:20












Related: But what if …?
– Scott
Nov 18 at 9:42




Related: But what if …?
– Scott
Nov 18 at 9:42










1 Answer
1






active

oldest

votes

















up vote
2
down vote



accepted










You can deal with the symlink with a simple variable:



symlink_flag=
if [[ $symlink_boolean == y ]]; then
symlink_flag=-L
fi
find $symlink_flag "$location" -maxdepth "$depth" -readable ...


Note that $symlink_flag is unquoted here, so if empty, it disappears. The value it has doesn't contain any wildcards or default IFS characters, so not quoting it doesn't cause any harm. The other variables should be quoted, since e.g. the location might well contain whitespace.



For the depth part, your best bet is to build the command line in an array:



arguments=()
if [[ $symlink_boolean == y ]]; then
arguments+=(-L)
fi
arguments+=("$location")
if [[ $depth_boolean == y ]]; then
arguments+=(-maxdepth "$depth")
fi
find "$arguments[@]" -readable -iname ...


You can put the nonchanging options on the find command line as above, or just unconditionally append them to the array and just run find "$arguments[@]".



See also:



  • How can we run a command stored in a variable?


  • Word Splitting in BashGuide

  • BashFAQ/050 or "I'm trying to put a command in a variable, but the complex cases always fail!"


Technically, you can also do what you propose with command substitution:



find $(if [[ $symlink_boolean == y ]]; then printf %s -L; fi) "$location"
$(if [[ $depth_boolean == y ]]; then echo -maxdepth $maxdepth; fi) ...


Though in general this is not optimal, the only way to produce multiple words from the command substitution is to have them space-separated and then split, but that again doesn't work well if there are words within that should contain whitespace. -maxdepth N should work, though.




As a side note, you can condense the conditions a bit by using e.g. [[ $symlink_boolean == [Yy]* ]]. It would check if the variable starts with a Y or a y. (If you don't mind stuff like YEAAHHH also being truthy values.) Use the regex match [[ $symlink_boolean =~ ^(y|yes)$ ]] or case $symlink_boolean in y|yes) echo "true";; esac to just allow the two values.






share|improve this answer






















  • Thank you so much for all your help. I've changed it up to build the command line into an array first as you suggested. Thanks for the info about conditions too.
    – kerrin
    15 hours ago










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',
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%2f482499%2fcombining-if-else-with-variables-in-find-command-in-bash-script%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








up vote
2
down vote



accepted










You can deal with the symlink with a simple variable:



symlink_flag=
if [[ $symlink_boolean == y ]]; then
symlink_flag=-L
fi
find $symlink_flag "$location" -maxdepth "$depth" -readable ...


Note that $symlink_flag is unquoted here, so if empty, it disappears. The value it has doesn't contain any wildcards or default IFS characters, so not quoting it doesn't cause any harm. The other variables should be quoted, since e.g. the location might well contain whitespace.



For the depth part, your best bet is to build the command line in an array:



arguments=()
if [[ $symlink_boolean == y ]]; then
arguments+=(-L)
fi
arguments+=("$location")
if [[ $depth_boolean == y ]]; then
arguments+=(-maxdepth "$depth")
fi
find "$arguments[@]" -readable -iname ...


You can put the nonchanging options on the find command line as above, or just unconditionally append them to the array and just run find "$arguments[@]".



See also:



  • How can we run a command stored in a variable?


  • Word Splitting in BashGuide

  • BashFAQ/050 or "I'm trying to put a command in a variable, but the complex cases always fail!"


Technically, you can also do what you propose with command substitution:



find $(if [[ $symlink_boolean == y ]]; then printf %s -L; fi) "$location"
$(if [[ $depth_boolean == y ]]; then echo -maxdepth $maxdepth; fi) ...


Though in general this is not optimal, the only way to produce multiple words from the command substitution is to have them space-separated and then split, but that again doesn't work well if there are words within that should contain whitespace. -maxdepth N should work, though.




As a side note, you can condense the conditions a bit by using e.g. [[ $symlink_boolean == [Yy]* ]]. It would check if the variable starts with a Y or a y. (If you don't mind stuff like YEAAHHH also being truthy values.) Use the regex match [[ $symlink_boolean =~ ^(y|yes)$ ]] or case $symlink_boolean in y|yes) echo "true";; esac to just allow the two values.






share|improve this answer






















  • Thank you so much for all your help. I've changed it up to build the command line into an array first as you suggested. Thanks for the info about conditions too.
    – kerrin
    15 hours ago














up vote
2
down vote



accepted










You can deal with the symlink with a simple variable:



symlink_flag=
if [[ $symlink_boolean == y ]]; then
symlink_flag=-L
fi
find $symlink_flag "$location" -maxdepth "$depth" -readable ...


Note that $symlink_flag is unquoted here, so if empty, it disappears. The value it has doesn't contain any wildcards or default IFS characters, so not quoting it doesn't cause any harm. The other variables should be quoted, since e.g. the location might well contain whitespace.



For the depth part, your best bet is to build the command line in an array:



arguments=()
if [[ $symlink_boolean == y ]]; then
arguments+=(-L)
fi
arguments+=("$location")
if [[ $depth_boolean == y ]]; then
arguments+=(-maxdepth "$depth")
fi
find "$arguments[@]" -readable -iname ...


You can put the nonchanging options on the find command line as above, or just unconditionally append them to the array and just run find "$arguments[@]".



See also:



  • How can we run a command stored in a variable?


  • Word Splitting in BashGuide

  • BashFAQ/050 or "I'm trying to put a command in a variable, but the complex cases always fail!"


Technically, you can also do what you propose with command substitution:



find $(if [[ $symlink_boolean == y ]]; then printf %s -L; fi) "$location"
$(if [[ $depth_boolean == y ]]; then echo -maxdepth $maxdepth; fi) ...


Though in general this is not optimal, the only way to produce multiple words from the command substitution is to have them space-separated and then split, but that again doesn't work well if there are words within that should contain whitespace. -maxdepth N should work, though.




As a side note, you can condense the conditions a bit by using e.g. [[ $symlink_boolean == [Yy]* ]]. It would check if the variable starts with a Y or a y. (If you don't mind stuff like YEAAHHH also being truthy values.) Use the regex match [[ $symlink_boolean =~ ^(y|yes)$ ]] or case $symlink_boolean in y|yes) echo "true";; esac to just allow the two values.






share|improve this answer






















  • Thank you so much for all your help. I've changed it up to build the command line into an array first as you suggested. Thanks for the info about conditions too.
    – kerrin
    15 hours ago












up vote
2
down vote



accepted







up vote
2
down vote



accepted






You can deal with the symlink with a simple variable:



symlink_flag=
if [[ $symlink_boolean == y ]]; then
symlink_flag=-L
fi
find $symlink_flag "$location" -maxdepth "$depth" -readable ...


Note that $symlink_flag is unquoted here, so if empty, it disappears. The value it has doesn't contain any wildcards or default IFS characters, so not quoting it doesn't cause any harm. The other variables should be quoted, since e.g. the location might well contain whitespace.



For the depth part, your best bet is to build the command line in an array:



arguments=()
if [[ $symlink_boolean == y ]]; then
arguments+=(-L)
fi
arguments+=("$location")
if [[ $depth_boolean == y ]]; then
arguments+=(-maxdepth "$depth")
fi
find "$arguments[@]" -readable -iname ...


You can put the nonchanging options on the find command line as above, or just unconditionally append them to the array and just run find "$arguments[@]".



See also:



  • How can we run a command stored in a variable?


  • Word Splitting in BashGuide

  • BashFAQ/050 or "I'm trying to put a command in a variable, but the complex cases always fail!"


Technically, you can also do what you propose with command substitution:



find $(if [[ $symlink_boolean == y ]]; then printf %s -L; fi) "$location"
$(if [[ $depth_boolean == y ]]; then echo -maxdepth $maxdepth; fi) ...


Though in general this is not optimal, the only way to produce multiple words from the command substitution is to have them space-separated and then split, but that again doesn't work well if there are words within that should contain whitespace. -maxdepth N should work, though.




As a side note, you can condense the conditions a bit by using e.g. [[ $symlink_boolean == [Yy]* ]]. It would check if the variable starts with a Y or a y. (If you don't mind stuff like YEAAHHH also being truthy values.) Use the regex match [[ $symlink_boolean =~ ^(y|yes)$ ]] or case $symlink_boolean in y|yes) echo "true";; esac to just allow the two values.






share|improve this answer














You can deal with the symlink with a simple variable:



symlink_flag=
if [[ $symlink_boolean == y ]]; then
symlink_flag=-L
fi
find $symlink_flag "$location" -maxdepth "$depth" -readable ...


Note that $symlink_flag is unquoted here, so if empty, it disappears. The value it has doesn't contain any wildcards or default IFS characters, so not quoting it doesn't cause any harm. The other variables should be quoted, since e.g. the location might well contain whitespace.



For the depth part, your best bet is to build the command line in an array:



arguments=()
if [[ $symlink_boolean == y ]]; then
arguments+=(-L)
fi
arguments+=("$location")
if [[ $depth_boolean == y ]]; then
arguments+=(-maxdepth "$depth")
fi
find "$arguments[@]" -readable -iname ...


You can put the nonchanging options on the find command line as above, or just unconditionally append them to the array and just run find "$arguments[@]".



See also:



  • How can we run a command stored in a variable?


  • Word Splitting in BashGuide

  • BashFAQ/050 or "I'm trying to put a command in a variable, but the complex cases always fail!"


Technically, you can also do what you propose with command substitution:



find $(if [[ $symlink_boolean == y ]]; then printf %s -L; fi) "$location"
$(if [[ $depth_boolean == y ]]; then echo -maxdepth $maxdepth; fi) ...


Though in general this is not optimal, the only way to produce multiple words from the command substitution is to have them space-separated and then split, but that again doesn't work well if there are words within that should contain whitespace. -maxdepth N should work, though.




As a side note, you can condense the conditions a bit by using e.g. [[ $symlink_boolean == [Yy]* ]]. It would check if the variable starts with a Y or a y. (If you don't mind stuff like YEAAHHH also being truthy values.) Use the regex match [[ $symlink_boolean =~ ^(y|yes)$ ]] or case $symlink_boolean in y|yes) echo "true";; esac to just allow the two values.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 18 at 9:44

























answered Nov 18 at 9:36









ilkkachu

53.8k781146




53.8k781146











  • Thank you so much for all your help. I've changed it up to build the command line into an array first as you suggested. Thanks for the info about conditions too.
    – kerrin
    15 hours ago
















  • Thank you so much for all your help. I've changed it up to build the command line into an array first as you suggested. Thanks for the info about conditions too.
    – kerrin
    15 hours ago















Thank you so much for all your help. I've changed it up to build the command line into an array first as you suggested. Thanks for the info about conditions too.
– kerrin
15 hours ago




Thank you so much for all your help. I've changed it up to build the command line into an array first as you suggested. Thanks for the info about conditions too.
– kerrin
15 hours ago

















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f482499%2fcombining-if-else-with-variables-in-find-command-in-bash-script%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

How to check contact read email or not when send email to Individual?

Displaying single band from multi-band raster using QGIS

How many registers does an x86_64 CPU actually have?