Find the answer to your Linux question:
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 ...
  1. #1
    Linux Newbie imranka's Avatar
    Join Date
    Dec 2007
    Location
    Kolkata
    Posts
    177

    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:
    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
    This is not the complete code, but shows the place where I am facing problem.

    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

  2. #2
    Linux 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.
    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
    Just write your program so that it does the most important work entirely inside the loop, once for each result from "find".

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...