You are not logged in.
Pages: 1
I have a partial file name, suppose file=night
I want to find files having similar names with *$file*
since given file names can contain spaces, the search string should be '*$file*'
so I do q=\' and string=$q*${file}*$q
echo $string produces '*night*'
but when I do
find <location> -iname ${string} , string expands to ''\''*night*'\''' and I get no search output.
If string is assigned like string='*night*', it works; but if string="'*night*'" it doesn't (although echo produces expected output).
I need the single quote encapsulation because there maybe spaces in the file name.
EDIT: Even "find <location> -iname $(echo "$sstring")" doesn't work.
Basically, when string doesn't have quotes embedded in it, it works. Otherwise not.
I'm looking for a solution..
Here's the script and the output if you need.
Thanks.
#!/bin/bash -x
export mlibrary='/media/Entertainment/songs/'
find_and_play() {
echo -n 'Track name: '
read track
q=\'
sstring=$q*"$track"*$q
echo ${sstring}
IFS='
'
sfiles=(`find ${mlibrary} -depth -iname "$sstring"`)
#echo ${sfiles[0]}
for t in `seq 1 ${#sfiles[@]}`; do
echo "$t==> ${sfiles[$t]}"
done
exit 0
}
find_and_play
+ export mlibrary=/media/Entertainment/songs/
+ mlibrary=/media/Entertainment/songs/
+ find_and_play
+ echo -n 'Track name: '
Track name: + read track
night
+ q=''\'''
+ sstring=''\''*night*'\'''
+ echo ''\''*night*'\'''
'*night*'
+ IFS='
'
+ sfiles=(`find ${mlibrary} -depth -iname "$sstring"`)
++ find /media/Entertainment/songs/ -depth -iname ''\''*night*'\'''
+ echo
++ seq 1 0
+ exit 0
Last edited by debdj (2012-06-14 11:20:21)
Offline
That entire function can be replaced by something like:
read -p "Track name: " track
count=0
for f in "$(find . -name "*$track*")"; do
count++
echo "$count ==> $f"
done
Or, perhaps
read -p "Track name: " track
count=0;
find . -name "*$track*" -exec echo $((++count)) "==>" '{}' \;
But my "find-fu" is not as good as many others'.
Or even shorter, but a bit ridiculous:
count=0;
find . -name "*"`read -p "Track Name: "`"*" -exec echo $((++count)) "==>" '{}' \;
The overall point being, the more times you set a variable equal to another variable that was in turn set from another variable ... the more times you do that, the more trouble you're going to have keeping track of escaped quotes. In this case there is no purpose for all those intermediate variables. Ditch them.
Last edited by Trilby (2012-06-11 21:08:22)
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
Thanks for your response.
I actually need the sfiles array because I want to play the file/files based on selection.
And its working.
Although on your first example,
for f in "$(find . -name "*$track*")"
won't really do, because it'll treat the entire result as one string for those quotes.
Anyway, thanks.
Offline
Nor would it be proper to iterate over if it were unquoted. For iterates over words in a list, not command output.
IFS=$'\n' read -rd '' -a files < <(find . -type f -name "*$track*")
for f in "${files[@]}"; do
somethingwith "$f"
done
Last edited by falconindy (2012-06-11 23:32:24)
Offline
@falconindy I guess the -d option to read defines delimiter and -a is array? Its not documented in the man page.
Anyway, my script is done.
You can see it here: https://bbs.archlinux.org/viewtopic.php … 9#p1115539
Thanks to both of you.
Last edited by debdj (2012-06-13 13:38:10)
Offline
@falconindy I guess the -d option to read defines delimiter and -a is array? Its not documented in the man page.
It's in the bash man page:
read [-ers] [-a aname] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t time‐
out] [-u fd] [name ...]
One line is read from the standard input, or from the file descriptor fd supplied
as an argument to the -u option, and the first word is assigned to the first name,
the second word to the second name, and so on, with leftover words and their inter‐
vening separators assigned to the last name. If there are fewer words read from
the input stream than names, the remaining names are assigned empty values. The
characters in IFS are used to split the line into words. The backslash character
(\) may be used to remove any special meaning for the next character read and for
line continuation. Options, if supplied, have the following meanings:
-a aname
The words are assigned to sequential indices of the array variable aname,
starting at 0. aname is unset before any new values are assigned. Other
name arguments are ignored.
-d delim
The first character of delim is used to terminate the input line, rather
than newline.
....
"...one cannot be angry when one looks at a penguin." - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle
Offline
'man read' opens read (1P) on my system. read -h does list the options. Where's the man page for the read shell command?
Offline
'man read' opens read (1P) on my system. read -h does list the options. Where's the man page for the read shell command?
As well as what falconindy said, man bash then scroll down to its built-ins. The help is quicker for specifics, but I keep forgetting that option.
"...one cannot be angry when one looks at a penguin." - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle
Offline
Offline
Pages: 1