[Bash] How to expand path variable that contains spaces and wildcards
Hi all
First post here, I'm quite new with bash and now having bit of a trouble with path expansion of strings that contain some whitespace and wildcards First my script sources a configuration file that contains array assignments Code:
... Code:
IFS_DEFAULT="$IFS" Problem with default IFS seems to be that with it neither $pattern or "$pattern" work; it either interprets pattern as multiple words (because of spaces) and so expands to wrong paths or it ignores * because it's within quotes. Any suggestions as to how I could do this better ? Thanks! |
When you use the
Code:
"${BACKUP_TARGET_FILES[@]}" Can you use Code:
BACKUP_TARGET_FILES=( Code:
for value in ${BACKUP_TARGET_FILES[@]}; do Code:
|
Quote:
from bash man pages under "Special Parameters" Quote:
Quote:
Quote:
Code:
... But I'd prefer to let user do simple double quoting in config file and then do all the hard work in the script. |
Yes you are correct on the "${arrayvar[@]}" which is like the "$@" for the arguments. I did not read the '@' correctly.
When having delayed expansions it is also hard. If the stuff is fixed at the time you could try: Code:
my_array=( The use of spaces is really discourage (even in Windows) by any one that writes scripts (perl, python, batch, etc) bit windows does not allow the use of a '"' (quote in a name as they have to quote the name when working with them). Unix and Linux only that two characters that can not be in a name but many characters that can problems to people writting scripts. The not allowed characters are '/' and the character having a binary value of 0 (nul). But it is unwise to use lots of characters such as ! $ , ; ' " ( ) [ ] \ ... Just because a character can be used is not a GOOD reason to use them. |
Here's prrof of concept code without IFS manipulation
Code:
#!/bin/bash Code:
DEBUG: $pattern is '/tmp/d*/b*' |
Quote:
Code:
BACKUP_TARGET_FILE_PATTERNS[2]="/tmp/dir with space*/f*" # space+wildcard pattern Code:
DEBUG: $pattern is '/tmp/dir with space*/f*' Code:
... Maybe IFS manipulation is quite good solution afterall and not worth fixing? |
Quote:
Having thought about the actual problem and researched some alternatives, I think your present solution is probably optimal. You could make it a little neater by not storing and restoring IFS; simply unsetting IFS is functionally equivalent to having it set at the default value. Code:
unset IFS |
Code:
patterns=("/usr/*/foo*", "/var/r*/bar*"j, "/mnt/qux*") Quote:
|
Quote:
Nice, robust technique. I tried the find / -path approach but discarded it for a couple of reasons. The most important was that find does not regard the "/" character as special in -path patterns so "/etc/*.cfg" would match "/etc/foo/my.cfg" which is counter-intuitive. The second was that it searches the whole file system hierarchy which may be resource intensive. The technique could be modified if the search patterns did not have wildcarded directories in which case the search pattern could be parsed into directory and filename_pattern Code:
find "$directory" -maxdepth 1 -type f -name "filename_pattern" -print0 BTW, there's a typo in the done < <(find / -path "$pattern" -print0), which should be done < $(find / -path "$pattern" -print0) |
Quote:
Quote:
Code:
echo $(echo foo) Code:
foo |
Quote:
|
Quote:
Code:
http://freeyourip.oiihob.org/76743c05daab6e517da22463deec3092/strange_names.tbz |
All times are GMT -5. The time now is 08:59 PM. |