How to pass * as part of argument string to script?
Bo Berglund
bo.berglund at gmail.com
Wed Aug 25 08:22:57 UTC 2021
On Wed, 25 Aug 2021 09:00:03 +0100, Chris Green <cl at isbd.net> wrote:
>On Wed, Aug 25, 2021 at 09:24:37AM +0200, Bo Berglund wrote:
>> I am writing a script to prune a directory of certain files and it works fine
>> provided the pattern to search for is entered directly in the script.
>> But when I try to set it as a parameter on the command line the pattern seems to
>> be expanded before being read by the script...
>> How can I avoid this?
>>
>> Here is how I read the template argument:
>>
>> if [ -z "$2" ]; then
>> template="202*.mp4" #Default file template for listing
>> else
>> template="$2"
>> fi
>>
>> And here is how template is used:
>> cntall=`find . -maxdepth 1 -name "202*.mp4" -printf '.' | wc -m`
>> #cntall=`find . -maxdepth 1 -name "${template}" -printf '.' | wc -m`
>>
>> As shown it works OK using the first line.
>>
>> But if I move the comment to the line above and enter the string 202*.mp4 as
>> argument 2 on the command line then the script is no longer working.
>>
>> It turns out that $template is set to the first file name *matching* the pattern
>> with the entered wildcard *!
>>
>> So if I have these files:
>> 2021-08-12_myvideo.mp4
>> 2021-08-13_myvideo.mp4
>> 2021-08-14_myvideo.mp4
>> 2021-08-15_myvideo.mp4
>> 2021-08-16_myvideo.mp4
>> 2021-08-17_myvideo.mp4
>>
>> I expect cntall to be set to 6 but in fact it will be 1 because inside the
>> script the entered string 202*.mp4 intended as $template is expanded to be
>> 2021-08-12_myvideo.mp4, which when used as $template always will return 1 from
>> the call above...
>>
>> How can I use a template input with the script without Ubuntu expanding my input
>> before it gets to the script?
>>
>By changing the quoting! :-)
>
>You probably need a line something like:-
>
> template='202*.mp4' #Default file template for listing
>
>Otherwise, as you have found out, bash expands the *s there. Bash
>expands variables, *, etc. within " but not within '.
Well the problem is not the *default* template because that works fine.
If I make the call:
prunelist
it use a max count of 5 thanks to this, which I did not show:
if [ -z "$1" ]; then
cnt="5" #Leave at least 5 files in place with no argument
else
cnt=$1
fi
and the default template is then set by:
if [ -z "$2" ]; then
template="202*.mp4" #Default file template for listing
else
template="$2"
fi
but if I call the script as follows:
prunevideos 3 202*.mp4
then $template inside the script becomes 2021-08-12_myvideo.mp4 and only one
match is found.
Do you mean that there is no way I can transfer a * character into a script as
part of an argument?
For completeness here is the current (debug) state of the prunelist scrip, which
is called from the prunevideos script expecting a list of videos to remove:
#!/bin/bash
# List excess files to remove, leaving the number in the call argument in place
# Check target file argument
if [ -z "$1" ]; then
cnt="5" #Leave at least 5 files in place with no argument
else
cnt=$1
fi
if [ $cnt -lt "0" ]; then #Do not allow negative arguments
# echo "Negative file count not allowed!"
# echo " Usage: $0 [count [template]]"
exit
fi
if [ -z "$2" ]; then
template="202*.mp4" #File template for listing
else
template="$2"
fi
#echo "Template = $2 (${template})"
cntall=`find . -maxdepth 1 -name "202*.mp4" -printf '.' | wc -m`
#cntall=`find . -maxdepth 1 -name "${template}" -printf '.' | wc -m`
let "cntrem = $cntall - $cnt"
#echo "Template = ${template}"
#echo "Count = $cnt"
#echo "Leave = $cntrem"
if [ $cntrem -le "0" ]; then
exit
fi
videos=`printf "%s\n" 202?-*.mp4 | head -"$cntrem"`
#videos=`printf "%s\n ${template}" | head -"$cntrem"`
echo "$videos"
--
Bo Berglund
Developer in Sweden
More information about the ubuntu-users
mailing list