I have several files like Apple-AP01, Apple-AP02, Banana-AP05, Chocolate-RS33 and others in my home directory that are pulled from an ftp server. In the same home directory there are Folders like Fruit, Sweet, etc. And within these folders, there are subfolders with names like Apple-AP01, Apple-AP02, Chocolate-RS33, etc.

I need to run a script on my home directory such that once I have Apple-AP01, it knows to place it into the Fruit folder based on the "AP" keyword and then further place that into the Apple-AP01 folder. and for Chocolate-RS33, it needs to go into the Sweet folder based on the "RS" keyword and then further into the Chocolate-RS33 subfolder within the Sweet folder. I need this for all of my files. Can someone put a bash script that would work?

I've tried

for f in *.
    name=`echo "$f"|sed 's/ -.*//'`
    letter=`echo "$name"|cut -c1`
    mkdir -p "$dir"
    mv "$f" "$dir"

I think I need to use a for loop, but I’m not sure how to do it in bash.

  • for f in *.; do name=echo "$f"|sed 's/ -.*//' letter=echo "$name"|cut -c1 dir="DestinationDirectory/$letter/$name" mkdir -p "$dir" mv "$f" "$dir" done – ksuzy31 Nov 1 '17 at 18:34
  • I think I need to use a for loop but im not sure how to do it in bash – ksuzy31 Nov 1 '17 at 18:37
  • 1
    Neither cut nor sed know that apples are fruits or chocolates are sweets, so you need a mechanism to relate the files to the directories. – Philippos Nov 2 '17 at 9:16

Check, does it do what you want.

First way:


declare -A arr_map

arr_map=([AP]=Fruit [RS]=Sweet)

# Iterate through indexes of array
for keyword in "${!arr_map[@]}"; do
    # Search files containing the "-$keyword" pattern in the name
    # like "-RS" or "-AP". This pattern can be tuned to the better matching.
    for filename in *-"$keyword"*; do
        # if file exists and it is regular file
        if [ -f "$filename" ]; then
            # Remove these echo commands, after checking resulting commands.
            echo mkdir -p "$destination"
            echo mv -iv "$filename" "$destination"

Second way:


declare -A arr_map

arr_map=([AP]=Fruit [RS]=Sweet)

# Iterate through all files at once
for i in *; do
    # If the file is a regular and its name conforms to the pattern
    if [[ -f "$i" && "$i" =~ [A-Za-z]+-[A-Z]+[0-9]+ ]]; then
        # trim all characters before the dash: '-' from the beginning
        # trim all digits from the ending

        # if the arr_map contains this keyword
        if [[  ${arr_map["$keyword"]} != "" ]]; then
            # Remove these echo commands, after checking resulting commands.
            echo mkdir -p "$destination"
            echo mv -iv "$i" "$destination"
  • @ksuzy31 Does changing to echo mv -v "$keyword" "$destination" do, what you want? Without the -i option, the mv command doesn't prompt before overwrite a file. – MiniMax Nov 6 '17 at 20:53
  • Or Hi, what if I had apple02-05group-AP05 and have multiple hyphens and i'm still just looking for if it has keyword, AP, put it in Fruit folder and then make a subfolder with the name apple02-05group-AP05 with this inside it – ksuzy31 Nov 6 '17 at 21:30
  • @ksuzy31 I don't know. I tested both scripts on your original filenames (Apple-AP01, Apple-AP02, Banana-AP05, Chocolate-RS33) and they were working. If filenames differs from original examples, than it needed to tailor scripts for them. – MiniMax Nov 6 '17 at 21:32
  • @ksuzy31 apple02-05group-AP05 this kind filenames will be a problem, because the [A-Za-z]+-[A-Z]+[0-9]+ regex mathes only to Apple-AP01 kind. The [A-Za-z]+-[A-Z]+[0-9]+ means - one or more letters, then dash, then one or more capital letters, then one or more digits. So, another type of filenames wouldn't conform to this pattern. – MiniMax Nov 6 '17 at 21:35
  • hmm I see. Do you think there's some work around with the multiple hyphens because that's kind of what I have now. BTW thank you for above. You were right, I had the name wrong. But now I have to do these multiple hyphens but what if it was all caps like APPLE02-05GROUP-AP05. Do you think you could help me with a script that would put that into Fruit folder. and like CHOCOLATE-02GROUP-RS33 into Sweet folder. – ksuzy31 Nov 6 '17 at 21:39

This should cover most of what you want to do.



# Puts files into subdirectories named after themselves in a directory.

# add more loops for more ID-criteria

for f in *AP*; do
    mkdir -p "./fruit/$f";
    mv -vn "$f" "./fruit/$f/";

for f in *RS*; do
    mkdir -p "./sweet/$f";
    mv -vn "$f" "./sweet/$f/";
  • Hi. Thank you for this. It is pretty good and is almost what I want. I need this such that 2 things: 1. I need it so if I ever have the same name file or am updating a file, it will automatically place it in the right folder and subfolder. and 2. It will looks through all the key words and put them in the right folder and won't throw me an error if it doesn't find anything – ksuzy31 Nov 6 '17 at 21:28

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.