3

So I have a directory of like 200 of the the following types of files:

gre_6_c1_d34567.h3
gre_6_c1_d95543.h3
gre_6_c1_d42354.h3
gre_6_c1_d01452.h3
gre_6_c1_d23168.h3
gre_6_c1_435435.h3

The only difference between these files is the numbers after d. I have a text file that only contains the d number for like 50 of these files. If I could get the entire file name I would but this text file is the output of another script. Is there a way I can move these files to another directory using the d number from the text file?

0

Using sed e flag :

sed 's|^\(.*\)$|mv gre_6_c1_\1.h3 newdir/|e' list.txt

Above will move the files to newdir/ change it accordingly.

I assume on list.txt the number are as below separated by new line:

d34567
d23168

Run this to confirm:

sed 's|^\(.*\)$|mv gre_6_c1_\1.h3 newdir/|' list.txt
0

With bash 4, you could load an array with file names derived from the numbers in the "driver" file and then use the -t option of GNU mv to move them into a directory at one shot. Note

#read contents of driver_file into an array arr using mapfile
mapfile -t arr <driver_file

#define prefix and suffix variables
prefix=gre_6_c1_d
suffix=.h3

#prefix each array element
arr=("${arr[@]/#/$prefix}")

#suffix each array element
arr=("${arr[@]/%/$suffix}")

#use GNU mv's -t facility to move files into newdir
mv -t newdir/ "${arr[@]}"
  • I just wrote my first bash script yesterday so this is a little over my head. Can you explain it a little more in depth? – e1v1s May 17 '16 at 20:46
  • @e1v1s, some explanation added – iruvar May 18 '16 at 13:51
0

Reading the numbers from the file one by one and doing the move (assumes a POSIX shell):

while read -r number; do
   name="gre_6_c1_d$number.h3"
   [ -f "$name" ] && mv -i "gre_6_c1_d$number.h3" /other/directory
done <number.list

This also makes sure that the number yields the name of a file existing in the current directory before moving it to the other directory. The mv -i command will furthermore ask for confirmation before overwriting an existing file.


Since this question was tagged with , we could ask xargs to generate the list of numbers for us:

xargs sh -c '
    for number do
        name="gre_6_c1_d$number.h3"
        [ -f "$name" ] && mv "gre_6_c1_d$number.h3" /other/directory
    done' sh <number.list

This wouldn't speed anything up, but if your xargs provides a -P flag for running things in parallel, you could get a small speed boost:

xargs -P 5 -n 10 -h sh -c '
    for number do
        name="gre_6_c1_d$number.h3"
        [ -f "$name" ] && mv "gre_6_c1_d$number.h3" /other/directory
    done' sh <number.list

This would start at most five copies of the loop in parallel, and give each at most ten numbers each in batches.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.