Search code examples
bashfilecopymkdir

Find files in one directory from a list, copy to a new directory, and execute script


I have a file that looks like this:
file Gibbs kcal rel SS6.out -1752.138493 -1099484.425742 2.270331 S5.out -1752.138532 -1099484.450215 2.245858 SS3.out -1752.140319 -1099485.571575 1.124498 SS4.out -1752.140564 -1099485.725315 0.970758 SS1.out -1752.141887 -1099486.555511 0.140562 SS2.out -1752.142111 -1099486.696073 0.000000

What I want to do is find the files that are listed in the first column. These files are in the same directory as the file I am reading the list of files out of is. I then want to take these found files and copy them into a new directory. To the copied files in the new directory, I want to execute more commands. I want this to all be done in the same bash script as the generation of this file is done in this script.

I honestly have very little idea on how to go about executing this. I was thinking about some lines that look like

cat lowE | cut -d ' ' -f 1 >> lowfiles to call up the starting file and make a list of files in a new file

mkdir high To make the new directory called high

find | grep -f lowfiles To find the files listed in lowfiles

I don't know how to then copy those listed files into the new directory and shift the script so that it will now execute all further lines in the script on the files that are in that new directory.


Solution

  • It's not clear to me what lowfiles and high mean so I'll use source and destination.

    #!/bin/bash
    # I'm piping a command into a while loop here since I don't care
    # that it's creating a subshell. If you need to access variables
    # used inside the loop, or other context, then you should use a
    # while loop with a process substitution redirected to the done
    # statement instead.
    
    # I'm assuming the filenames don't contain any white space characters
    
    dest=destination
    mkdir "$dest"
    
    awk '{print $1}' lowE | while read -r filename
    do
        cp "$filename" "$dest"
        # each of your commands will go here if you are operating on files one at a time, e.g.
        do_the_thing_to "$filename"
    done
    

    If you're operating on the files as a group or you want to separate your processing, instead of including your commands in the loop above either:

    Do something to all of them:

    do_something "$dest"/*
    another_thing "$dest"/*
    

    or use another loop and iterate over those files:

    for filename in "$dest"/*
    do
        one_thing "$filename"
        another_thing "$filename"
    done
    

    In either case you would still use the first loop at the top, just without including your commands in it.