Find the answer to your Linux question:
Results 1 to 2 of 2
Hello everyone!! i'm new to shell scripting and am having a problem. I'm trying to write a bash script to scan all the sub directories in the directory path specified ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Jun 2012
    Posts
    3

    Bash Scripting Problem


    Hello everyone!! i'm new to shell scripting and am having a problem. I'm trying to write a bash script to scan all the sub directories in the directory path specified as an argument for .avi, .mp4, .mkv, and .wmv files which will be moved into a directory in my home folder but when the script encounters a file or directory name with white space characters it only gets the name up to the first white space character. I need to find a way to get the entire string including white space characters. Many thanks in advance!!


    This is my shell code:

    Code:
    #!/bin/bash
    
    
    #Shell Function "scandir()"
    
    scandir() {
           local dname="$1"
           local entry[100]=""
    
           cd $dname
           echo "********************"
           pwd
           echo "********************"
           
           for entry in $dname/*
           do
    		if [ -d "$entry" ]
    		then
    			scandir $entry
    		elif [ -f "$entry" ]
    		then
    			if [[ $entry == *.mp4 || $entry == *.avi || $entry == *.wmv || $entry == *.mkv ]]
    			then
    				mv -v "$entry" /home/gurbos/Videos
    			fi	
    		fi
          done
    
          cd ".."
    			
    }
    
    
    #Execute code
    
    scandir "$1"
    
    exit 0
    Last edited by gurbos; 06-30-2012 at 03:01 AM.

  2. #2
    Linux Enthusiast
    Join Date
    Jan 2005
    Location
    Saint Paul, MN
    Posts
    649
    Quote Originally Posted by gurbos View Post
    Hello everyone!! i'm new to shell scripting and am having a problem. I'm trying to write a bash script to scan all the sub directories in the directory path specified as an argument for .avi, .mp4, .mkv, and .wmv files which will be moved into a directory in my home folder but when the script encounters a file or directory name with white space characters it only gets the name up to the first white space character. I need to find a way to get the entire string including white space characters. Many thanks in advance!!


    This is my shell code:

    Code:
    #!/bin/bash
    
    
    #Shell Function "scandir()"
    
    scandir() {
           local dname="$1"
           local entry[100]=""
    
           cd $dname
           echo "********************"
           pwd
           echo "********************"
           
           for entry in $dname/*
           do
    		if [ -d "$entry" ]
    		then
    			scandir $entry
    		elif [ -f "$entry" ]
    		then
    			if [[ $entry == *.mp4 || $entry == *.avi || $entry == *.wmv || $entry == *.mkv ]]
    			then
    				mv -v "$entry" /home/gurbos/Videos
    			fi	
    		fi
          done
    
          cd ".."
    			
    }
    
    
    #Execute code
    
    scandir "$1"
    
    exit 0

    While you were attempting to get a solution to file names with spaces, your script does not handle directory (or folder) names that contain spaces. The general rule is that file name (and folder names) should be limited to characters that are allowed across Apple, Microsoft, and UNIX and that spaces should be avoided. In Linux (and Unix) there are only two characters not allowed in a name (nil (0x00) and '/'); however, there are many characters that would require special handling when in a script (think about the following characters '$', '!', '>', '<', '[', ']', '{', '}', '|' just to get your started).

    From Filename - Wikipedia, the free encyclopedia
    Many file system utilities prohibit control characters from appearing in filenames. In Unix-like file systems the null character, as that is the end-of-string indicator[6] and the path separator / are prohibited.

    Some file system utilities prohibit some particular characters from appearing in filenames:
    Character Name Reason
    / slash used as a path name component separator in Unix-like, Windows, and Amiga systems. (The MS-DOS command.com shell would consume it as a switch character, but Windows itself always accepts it as a separator.[7][vague])
    \ backslash Also used as a path name component separator in MS-DOS, OS/2 and Windows (where there are few differences between slash and backslash); allowed in Unix filenames, see Note 1
    ? question mark used as a wildcard in Unix, Windows and AmigaOS; marks a single character. Allowed in Unix filenames, see Note 1
    % percent used as a wildcard in RT-11; marks a single character.
    * asterisk
    or star used as a wildcard in Unix, MS-DOS, RT-11, VMS and Windows. Marks any sequence of characters (Unix, Windows, later versions of MS-DOS) or any sequence of characters in either the basename or extension (thus "*.*" in early versions of MS-DOS means "all files". Allowed in Unix filenames, see note 1
    : colon used to determine the mount point / drive on Windows; used to determine the virtual device or physical device such as a drive on AmigaOS, RT-11 and VMS; used as a pathname separator in classic Mac OS. Doubled after a name on VMS, indicates the DECnet nodename (equivalent to a NetBIOS (Windows networking) hostname preceded by "\\".)
    | vertical bar
    or pipe designates software pipelining in Unix and Windows; allowed in Unix filenames, see Note 1
    " quote used to mark beginning and end of filenames containing spaces in Windows, see Note 1
    < less than used to redirect input, allowed in Unix filenames, see Note 1
    > greater than used to redirect output, allowed in Unix filenames, see Note 1
    . period
    or dot allowed but the last occurrence will be interpreted to be the extension separator in VMS, MS-DOS and Windows. In other OSes, usually considered as part of the filename, and more than one period (full stop) may be allowed.

    Note 1: While they are allowed in Unix file and folder names, most Unix shells require certain characters such as spaces, <, >, |, \, and sometimes :, (, ), &, ;, #, as well as wildcards such as ? and *, to be quoted or escaped:

    five\ and\ six\<seven (example of escaping)
    'five and six<seven' or "five and six<seven" (examples of quoting)

    In Windows utilities the space and the period are not allowed as the final character of a filename.[8] The period is allowed as the first character, but certain Windows applications, such as Windows Explorer, forbid creating or renaming such files (despite this convention being used in Unix-like systems to describe hidden files and directories). Among workarounds are using different explorer applications or saving a file with the desired filename from within an application .[9]

    Some file systems on a given operating system (especially file systems originally implemented on other operating systems), and particular applications on that operating system, may apply further restrictions and interpretations. See comparison of file systems for more details on restrictions.

    In Unix-like systems, MS-DOS, and Windows, the filenames "." and ".." have special meanings (current and parent directory respectively).

    In addition, in Windows and DOS utilities, some words might also be reserved and can not be used as filenames.[9] For example, DOS Device file:

    CON, PRN, AUX, CLOCK$, NUL
    COM0, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9
    LPT0, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9.

    Systems that have these restrictions cause incompatibilities with some other filesystems. For example, Windows will fail to handle, or raise error reports for, these legal UNIX filenames: aux.c, q"uote"s.txt, or NUL.txt.

    NTFS filenames that are used internally include:

    $Mft, $MftMirr, $LogFile, $Volume, $AttrDef, $Bitmap, $Boot, $BadClus, $Secure,
    $Upcase, $Extend, $Quota, $ObjId and $Reparse
    That said here is your script that allows for spaces within directory names and in the file names (it also handled *.AVI, *.Avi, ... as well).
    Code:
    #!/bin/bash
    
    
    #Shell Function "scandir()"
    
    scandir() {
        local dname="$1"
        local entry docopy
    
        cd "${dname}"
        echo "********************"
        pwd
        echo "********************"
           
        ls -1 | while read entry; do
    		if [ -d "${entry}" ] ; then
    			scandir "$entry"
    		elif [ -f "$entry" ] ; then
                case "${entry##*\.}" in
                    [Mm][Pp]4)    docopy=1 ;;
                    [Aa][Vv][Ii]) docopy=1 ;;
                    [Ww][Mm][Vv]) docopy=1 ;;
                    [Mm][Kk][Vv]) docopy=1 ;;
                    *)            docopy=0 ;;
                esac
    			if [ "${docopy}" -eq 1 ] ; then
                    # The desitiation location should be passed in as well...
    				mv -v "${entry}" /home/gurbos/Videos
    			fi	
    		fi
        done
        cd ..
    }
    
    # pass in as many directories as you like..
    for dname in "$@"; do
        scandir "${dname}"
    done

Posting Permissions

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