Page 3 of 3 FirstFirst 123
Results 21 to 28 of 28

Thread: Script for finding string in filename then copy file

  1. #21
    Join Date
    Feb 2009
    Location
    Arcadia, CA USA
    Beans
    502
    Distro
    Ubuntu Mate 22.04 Jammy Jellyfish

    Re: Script for finding string in filename then copy file

    @steeldriver
    The code fully works for me - thanks for the further explanation of Vaphell's code. While I do not understand the substitution coding, I should have tried just "~/Desktop" vs "/rocky/Desktop" etc. And I will apply that same code for the destination line.

    So for others that may be looking, I present the full code below which is my script file, made executable, and placed on the Desktop where the photo folders reside. I remmed the original line where the full path must be entered for "source".
    Code:
    #!/bin/bash
    
    #use:  copy selected files from any number of folders in a directory to a destination folder
    #where selection is governed by a search of ea file name for a specified string
    
    gnome-terminal -x bash -c '
    echo "Copy Select Files From Many Folders to a Single Folder"
    echo ""
    read -p "Enter full path to <dir> with image folders: " source; 
    read -p "Enter destination folder for copied image files: " catch;
    read -p "Enter string to search for within file names: " string;
    echo "$source"; echo "$catch"; echo "$string";
    
    #find "$source" -type f -iname "*$string*" -exec cp -t "$catch" -- {} +;
    
    find "${source/#~\//$HOME/}" -type f -iname "*$string*" -exec cp -t "$catch" -- {} +;
    
    sleep 10 '
    Thank you both for getting me through the syntax and coding issues.
    mark

  2. #22
    Join Date
    Feb 2009
    Location
    Arcadia, CA USA
    Beans
    502
    Distro
    Ubuntu Mate 22.04 Jammy Jellyfish

    Re: Script for finding string in filename then copy file

    I do not understand the behavior of acceptable paths for entry #2, ie "catch", in the script presented in my post #21(31 Dec 14). The folder to receive the selected files (in response to an input for "catch", I name "catch-it" and it is located at /home/rocky/Desktop/catch-it. The 1st and 3rd entries for "source" location and "string" to search for, cause me no grief.

    The following are entries and results for inputs to catch, the 2nd entry required in the script:
    catch-it - this works.
    /home/rocky/Desktop/catch-it - this works.
    ~/Desktop/catch-it - THIS DOES NOT WORK.

    1) Why does catch-it alone work with no path information explicitly given?
    2) Why doesn't ~/Desktop/catch-it work vs fouling with "No such file or directory" msg?

    mark
    Last edited by mark bower; April 9th, 2015 at 09:27 PM.

  3. #23
    Join Date
    Aug 2011
    Location
    47°9′S 126°43W
    Beans
    2,172
    Distro
    Ubuntu 16.04 Xenial Xerus

    Re: Script for finding string in filename then copy file

    Because "~" is not replaced by /home/{your_id} when in quotes. You can use:
    Code:
    "$HOME/Desktop/Catch"
    or the more contrived:
    Code:
    ~/"Desktop/Catch"
    Warning: unless noted otherwise, code in my posts should be understood as "coding suggestions", and its use may require more neurones than the two necessary for Ctrl-C/Ctrl-V.

  4. #24
    Join Date
    Feb 2009
    Location
    Arcadia, CA USA
    Beans
    502
    Distro
    Ubuntu Mate 22.04 Jammy Jellyfish

    Re: Script for finding string in filename then copy file

    I modified my post #22 to eliminate quotes which were misleading; I used them for emphasis in my text, but not in the responses required for the script.
    So now I ask again with respect to the script in post #21:

    1) Why does catch-it alone work with no path information explicitly given?
    2) Why doesn't ~/Desktop/catch-it work vs fouling with "No such file or directory" msg?

  5. #25
    Join Date
    Jul 2007
    Location
    Poland
    Beans
    4,499
    Distro
    Ubuntu 14.04 Trusty Tahr

    Re: Script for finding string in filename then copy file

    Standalone "catch-it" is reachable from the dir you are running the script from so it works pretty much by accident.
    Like ofnuts said, ~ cannot be quoted nor stored in variables, otherwise bash won't see it and expand it by default. Bash doesn't look inside strings/vars for ~.

    If you want to be able to type in ~, store it in variables and have things work, you need to use the same trick that was applied to find's root dir, ie expand the variable in question with substitution of ${var/#~\//$HOME/}. Once you do that, /home/username/... will be used.

    the gist of it.

    Code:
    $ mkdir -p ~/test
    $ test="~/test"
    $ [[ -e $test ]] && echo true || echo false   # test if exists
    false
    $ [[ -e ${test/#~\//$HOME/} ]] && echo true || echo false    # test if exists
    true
    
    
    $ bash -c 'x="~/Desktop/some-dir"; echo "$x => ${x/#~\//$HOME/}"'
    ~/Desktop/some-dir => /home/vaphell/Desktop/some-dir
    Last edited by Vaphell; April 10th, 2015 at 02:22 AM.
    if your question is answered, mark the thread as [SOLVED]. Thx.
    To post code or command output, use [code] tags.
    Check your bash script here // BashFAQ // BashPitfalls

  6. #26
    Join Date
    Feb 2009
    Location
    Arcadia, CA USA
    Beans
    502
    Distro
    Ubuntu Mate 22.04 Jammy Jellyfish

    Re: Script for finding string in filename then copy file

    o.k. thank you both; "~ cannot be quoted nor stored in variables" really makes sense for me. Vaphell, based on my experience level I will have to spend some time on your further explanation to understand/get the gist of it.

    The script works marvelously; my title for it is "copy_selected_files.sh". I have about 1,800 35mm family slides scanned and stored in 3 major directories. When I run the script using my daughter's name, all of the directories and sub-directories are accessed and shortly all the slides with her name in a file name are transfered to the catch folder. I should say that each digital image has everyones name who is in the photo, included in the file name. The script makes it very tidy to segregate the photos by person and prepare a DVD of photos including that person.

    I hope my satisfaction with this thread is more reward for you to continue to help others.

    thanks
    mark
    Last edited by mark bower; April 10th, 2015 at 04:08 PM.

  7. #27
    Join Date
    Jul 2007
    Location
    Poland
    Beans
    4,499
    Distro
    Ubuntu 14.04 Trusty Tahr

    Re: Script for finding string in filename then copy file

    Code:
    $ x=~/abc
    $ echo "$x"
    /home/vaphell/abc
    bash sees that naked ~ in the code, right off the bat substitutes it with full home dir before doing anything else with this code. Assignment never sees ~, gets /home/user/abc instead and that's the value stored in $x here.

    Code:
    $ x="~/abc"
    $ echo "$x"
    ~/abc
    this is pretty much equivalent to your scenario. When you prompt user for input, stuff gets saved in the variable verbatim. If you typed in ~, it's going to be literally ~. There is no dir that is literally named '~' so you get errors. That means that you need to process that ~ alias by hand to the true value before trying to access the path.

    You can do this with builtin ${x/pattern/replacement} expansion.
    pattern obviously is going to be ~ and the replacement is going to be $HOME=/home/username. If the pattern is prefixed with #, it forces the matching only at the start, ~'s in the middle/at the end are going to be ignored.


    Code:
    $ x="~/abc~"
    $ echo "${x/#~/====}"
    ====/abc~
    $ echo "${x/#~/$HOME}"
    /home/vaphell/abc~
    Note that my in my previous posts i replaced ~/ with $HOME/ because reasons (~user is a valid alias too so ~=$HOME is not always a rock solid assumption) but it won't work if you type ~ alone.


    '~' -> $HOME might be just enough for your needs, but you could also write a tidy function that translates stuff and abstracts the gritty details away, eg

    Code:
    unroll()
    {
      if [[ $1 = '~' ]]    # ~
      then
          echo "$HOME"
      elif [[ $1 = '~'/* ]]     # ~/stuff
      then
          echo "$HOME/${1#*/}"
      elif [[ $1 = '~'[[:alnum:]]* ]]    # ~user/stuff, looks in /etc/passwd for user's home dir
      then
          local id=${1#'~'}; id=${id%%/*}
          IFS=: read -r _ _ _ _ _ hdir _ < <( grep "^$id:" /etc/passwd )
          [[ -n "$hdir" ]] && echo "$hdir/${1#*/}" 
      else
          echo "$1"
      fi
    }
    
    unrolled_find_dir=$( unroll "$find_dir" )
    unrolled_dest_dir=$( unroll "$dest_dir" )
    that function in action:
    Code:
    $ unroll '~/abc~'
    /home/vaphell/abc~
    $ unroll '~pulse/x/~'
    /var/run/pulse/x/~
    $ unroll '~root/aaa'
    /root/aaa
    $ unroll '/usr/bin'
    /usr/bin
    if your question is answered, mark the thread as [SOLVED]. Thx.
    To post code or command output, use [code] tags.
    Check your bash script here // BashFAQ // BashPitfalls

  8. #28
    Join Date
    Feb 2009
    Location
    Arcadia, CA USA
    Beans
    502
    Distro
    Ubuntu Mate 22.04 Jammy Jellyfish

    Re: Script for finding string in filename then copy file

    o.k. Vaphell - your creating more homework for me. Thanks

Page 3 of 3 FirstFirst 123

Tags for this Thread

Bookmarks

Posting Permissions

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