alexd106 alexd106 - 1 month ago 8
Linux Question

creating directory from filename and move bash

I have a load of files

BR0200.aaa.tsv
BR0200.bbb.tsv
BR0200.ccc.tsv
BR0210.aaa.tsv
BR0210.bbb.tsv
BR0210.ccc.tsv
W0210.aaa.tsv
W0210.aaa.tsv
W0210.aaa.tsv


I would like to create a series of directories based on the first part of the filename up to the first '.'

BR0200
BR210
W0210


and then move the associated files to the correct directories (i.e. all BR0200.* files to BR0200 directory).

I have had a stab at a bash script but I keep getting errors. Any advice would be gratefully received.

#!/bin/bash

for file in BR* W0*; do
dir = "${file%%.*}"
if [-e $dir];then
mv "$file" "$dir"
else
mkdir -p "$dir"
mv "$file" "$dir"
fi
done


Sorry if this is a basic question. I have tried searching the web, but with no result.

Answer

There's no whitespace allowed around the = in an assignment.

dir="${file%%.*}"

Conversely, whitespace is required in a test.

if [ -e $dir ]; then
    ^       ^

As far as stylistic improvements, it doesn't hurt to do an unnecessary mkdir -p, so you can get rid of the if statement.

Quotes aren't required in an assignment, so you can remove them from the dir= line. Quoting is a good idea everywhere else though, so don't delete the other quotes.

It might be good to add an extra .* to the for loop. That way if you run the script more than once it won't try to move those newly-created sub-directories. And a neat trick (though not necessarily an improvement) is to shorten BR*.* W0*.* to {BR,W0}*.*.

for file in {BR,W0}*.*; do
    dir=${file%%.*}
    mkdir -p "$dir"
    mv "$file" "$dir"
done