-1

I have a .txt file containing a column of IDs and their ages (as integers). I've already created separate folders in my directory for each age category (ranging from 20-86). For every ID in my .txt file I would like to move their image (which is currently stored in the folder "data") to the appropriate folder, based on their age category listed in column two of my .txt file.

Any help on how to do this in Linux would be really appreciated!

Updated example with files ending in different suffixes.

Current working directory:

data/ 20/ 21/ 22/ 23/ 24/ ...

text file:

ID001 21
ID002 23
ID003 20
ID004 22
ID005 21

ls data/

ID001-XXX-2125.jpg
ID002-YYY-2370.jpg
ID003-XXX-2125.jpg
ID004-YYY-2370.jpg
ID005-XXX-2125.jpg

Desired output:

20/
ID003-XXX-2125.jpg

21/
ID001-XXX-2125.jpg
ID005-XXX-2370.jpg

22/
ID004-YYY-2370.jpg

23/
ID002-YYY-2370.jpg
M_Oxford
  • 361
  • 4
  • 11
  • 2
    Please [edit] your question to add the expected output and to show your attempt to solve the problem yourself so we can help you with that. See [ask]. – Ed Morton Jan 15 '21 at 13:37

3 Answers3

2
while read fil id
do
    mv -f "data/"*"$fil"*".jpg" "$id/"
done < file

Read the two fields from the file (called file in this case) in a loop and use the variables to construct and execute the mv command.

Raman Sailopal
  • 12,320
  • 2
  • 11
  • 18
2

As you suggest, awk can do this kind of task (though see Ed Morton's remark below). You may try the following, which is tested with GNU awk. From your working directory you can do:

awk '{system("mv data/"$1"*.jpg " $2)}' inputfile

Explanation: Here the system() function is used. The system() function allows you to execute a command supplied as an expression. In this case:

  1. We use the mv (move) command and use the first field $1 in the input file to address the JPG file in the data directory.
  2. Then we use the second field $2 of the input file for the destination directory.

The system() function is modeled after the standard C library function. Further reading in The GNU Awk User’s Guide

Thomas Hansen
  • 775
  • 1
  • 6
  • 17
  • 1
    Thank you Thomas! What if each of my files have a slight different suffix? e.g. "-2125.jpg", "-2124.jpg" could I do the following? ```awk '{system("mv data/"$1"*.jpg " $2)}' inputfile``` – M_Oxford Jan 15 '21 at 12:42
  • 1
    awk is a tool to manipulate text. A shell is a tool to manipulate files and processes and sequence calls to tools. You're trying to use awk as if it were a shell and in so doing spawning a subshell once per input line, doing `shell { awk { system { shell { mv } } } }` instead of just `shell { mv }` and exposing the input data unquoted to the shell for interpretation with the associated security issues and potential for failures based on input values, environment settings, contents of the directory you run the script from, etc. In short - no, awk is not well suited for this kind of task. – Ed Morton Jan 15 '21 at 13:34
0

Consider having your .txt file is in your current working directory. Can you try this written and tested script?

#!/bin/sh    
DIR_CWD="/path/to/current_working_directory"
cd "$DIR_CWD/data"
    for x in *; do
        ID_number=`echo $x | awk -F"-" '{print $1}'`
        DIR_age=`cat "$DIR_CWD/file.txt" | grep $ID_number | awk '{print $2}'`
        mv -- "$DIR_CWD/data/$x" "$DIR_CWD/$DIR_age"
    done

Note that DIR_CWD must be stated as the path of your current working directory.