Move files based on directory name (Linux / Debian / #!) - linux

Question:
How do I move files from many sub-directories with the same name to a single directory of that name. All files in multiple directories named X should get moved together into one directory named X.
Example file structure:
(The real structure is 200-300 directories at the level I've marked as 1, 2, 3, etc., with varying numbers of directories below that.)
(Note all labels like Group _ are just that--labels. The actual names are irregular.)
Disk
1
Library
Music
Group A
Files
Files
Files
Group B
Files
Files
Files
2
Library
Music
Group B
Files
Files
Files
Group C
Files
Files
Files
3
Library
Music
Group C
Files
Files
Files
Group D
Files
Files
Files
The goal is to have files in various sub-directories with name "Group X" moved into a single directory with name "Group X", like so:
Disk
1
Library
Music
Group A
Files
Files
Files
Group B
Files
Files
Files
Files
Files
Files
Group C
Files
Files
Files
Files
Files
Files
Group D
Files
Files
Files
Thanks!

You would do something like:
dest="Group A"
find -type f |
grep $dest |
while read filename
do
echo mv $filename ${dest}/$(basename $filename)
done

Related

How to zip files one by one in a directory in linux

I have a directory where there are files -:
abc_002.txt
abc_003.txt
abc_004.txt
abc_005.txt
xyz_001.txt
for_ex.sh
abc_001.txt
I want to gzip only files starting with names abc, like abc*.
for file in abc*.txt
do
gzip $file
done

How to copy files from a given directory into random directories of a target directory

I have a directory /Garbage which contains files Garbage-XXX where
XXX is a random number.
I have a directory /Target which has several subdirectories.
How can I tell bash to copy/move files from /Garbage into random subdirectories within /Target?
I am not a bash expert but I can hint the steps you need to take:
declare an array which will store a serial number with all the
subdirectory names
iterate through all subdirectories of /Target
with a for loop
place the loop number with the subdirectory name
into the array declared in step 1
iterate through all files of /Garbage with a for
loop (for filename in /Garbage/*.*)
copy or move each file within
the loop to a subdirectory of /Target given by a random number
between 0 and the size of your array (shuf -i
0-(${#arrayname[*]}-1) -n 1) which then used to retrieve the random number's corresponding subdirectory name from the array

Create a text file containing list of (relative paths to) files in a directory?

Suppose I am standing on a directory. Inside there's another directory called inside_dir containing a huge number of files. I want to create a file containing a list of all the files inside inside_dir, listed as the relative path to the files. That is, if there is a file called file1 inside inside_dir, the corresponding line in the list file should be inside_dir/file1.
Since the number of files is huge, just doing ls inside_dir/* > list.txt won't work because it will complain about having too many arguments.
find inside_dir -type f > list.txt

Diff two directories in linux then output any changed files to a new directory

What is the best way of getting the differences between two directories then outputting only what has changed to a third directory while still maintaining proper directory/file hierarchy?
diff gets me a list ( diff -rq dir1 dir2 ):
Files dir1/1/2/3/file.php and dir2/1/2/3/file.php differ
Files dir1/2/1/1/file.html and dir2/2/1/1/file.html differ
Files dir1/3/file.css and dir2/3/file.css differ
Only in dir1/1/2/3/: file.xml
Is there a single command that will output:
dir3/1/2/3/file.php
dir3/2/1/1/file.html
dir3/3/file.css
dir3/1/2/3/file.xml

How to move and number files?

I working with linux, bash.
I have one directory with 100 folders in it, each one named different.
In each of these 100 folders, there is a file called first.bars (so I have 100 files named first.bars). Although all named first.bars, the files are actually slightly different.
I want to get all these files moved to one new folder and rename/number these files so that I know which file comes from which folder. So the first first.bars file must be renamed to 001.bars, the second to 002.bars.. etc.
I have tried the following:
ls -d * >> /home/directorywiththe100folders/list.txt
cat list.txt | while read line;
do cd $line;
mv first.bars /home/newfolder
This does not work because I can't have 100 files, named the same, in one folder. So I only need to know how to rename them. The renaming must be connected to the cat list.txt, because the first line is the folder containing the first file wich is moved and renamed. That file will be called 001.bars.
Try doing this :
$ rename 's/^.*?\./sprintf("%03d.", $c++)/e' *.bar
If you want more information about this command, see this recent response I gave earlier : How do I rename multiple files beginning with a Unix timestamp - imapsync issue
If the rename command is not available,
for d in /home/directorywiththe100folders/*/; do
newfile=$(printf "/home/newfolder/%d.bars" $(( c++ )) )
mv "$d/first.bars" "$newfile"
done

Resources