Results 1 to 2 of 2
Hi,
I am trying to write a bash script to sync newly founded files in my local harddisk with my external harddisk. There, I am facing trouble to extract the ...
- 04-22-2011 #1
dirname basename problem with files/dir with whitespace
Hi,
I am trying to write a bash script to sync newly founded files in my local harddisk with my external harddisk. There, I am facing trouble to extract the dirname or basename for files/directory which has whitespace character.
My codes are as follows:
This is not the complete code, but shows the place where I am facing problem.Code:#!/bin/bash DEST_PATH=/media/xternaldisk/imran SRC_PATH_COMMON="." # first go the source dir cd /home/kaziray # search for newly added files #cnt_new=`find ./ -mtime -2 | wc -l` arr_new_f=(`find ./ -type f \( ! -regex '.*/\..*' \) -mtime -4`) # create an array containing new files which is not hidden for element in "${arr_new_f[@]}" do # echo "full path and file: " $element tmp_path=`dirname "$element"` # get the filepath echo "path :$tmp_path" mirror_path=${tmp_path##$SRC_PATH_COMMON} # echo "mirror path: $mirror_path" # echo "filename" `basename "${element}"` tmp_ext=`basename "${element##*.}"` # get the file extension echo $tmp_ext
Can somebody help me to solve this?
Thanks.Imran
Linux User #467555 | Debian Squeeze | Intel(R) Core(TM)2 Duo CPU 4500 @ 2.20GHz | Gigabyte GA-G41MT-ES2L
| 2 GB RAM | 320 GB SATA | Kernel: 2.6.32-5-686
- 04-22-2011 #2Linux Newbie
- Join Date
- Nov 2008
- Location
- Tokyo, Japan
- Posts
- 243
The problem is not with "basename" I think. You can try it on an ordinary file with spaces in the name, it works fine. The problem is with Bash's array syntax. New elements are added to the array separated by spaces, even in evaluated strings. So array=(`echo "one two"`) will have two items in the array, "one" and "two", not a single item "one two".
Really, the best solution is NOT to use arrays at all. Try instead to pipe the output of find to a parenthasized sub-process, then use the "read" builtin command to read each entry line-by-line.Just write your program so that it does the most important work entirely inside the loop, once for each result from "find".Code:#!/bin/bash #This is a very useful technique. find ./ -type f \( \! -regex '.*/\..*' \) -mtime -4 | \ ( while read element do #On each loop, 'element' will evaluate to the next result from "find" echo "element=\"$element\"" tmp_path=`dirname "$element"` # get the filepath echo "path :$tmp_path" mirror_path=${tmp_path##"$SRC_PATH_COMMON"} echo "mirror path: $mirror_path" echo "filename" `basename "${element}"` tmp_ext=`basename "${element##*.}"` # get the file extension echo $tmp_ext done ) #The commands inside the parentheses are running in a child Bash #process, so assigning variables in this processes will NOT be #visible to the rest of your program. echo "${tmp_path}${mirror_path}${tmp_ext}" #Produces no output


Reply With Quote