Shell script to copy specific files in directory using loops - shell

I'm trying to copy only specific files from a directory which has n number of files? Can I try that using loop?

Assuming Unix/Linux as you asked for a shell script
cd somedir
for F in *.dat
do
echo about to copy $F
cp $F /home/backup
done
would copy all files in somedir that ended in .dat to the directory /home/backup

Related

Move files and prepend filename

I am having difficulty moving files and prepending to the files with Bash.
#!/bin/bash
CAT="WFS_CAT"
for FILENAME in /foo/bar/20*
do
mv "${FILENAME##*/}" "${CAT}.${FILENAME##*/}"
done;
The command errors out. It tries to move the full directory name and prepend to that instead of the individual files.
In this case, it should be much simpler to change the directory to the one your files are located in, as your move command only renames files in this directory. Do you mind trying this?
pushd /foo/bar
for FILENAME in 20*; do
echo mv "${FILENAME}" "${CAT}.${FILENAME}"
done;
popd

Unix shell scripting

I have write shell script to find the particular filename in the directory and create list file to copy the filenames automatically in that list file. But my script is not working list file is not created automatically. I don't know the issue in my script.
Scripts='/app/file'
SrcFiles='/app/file/Mainfiles'
cd "$SrcFiles"
touch SOURCE.LIST
chmod 777 SOURCE.LIST
cd "$Scripts"
cd "$SrcFiles"
for f in *.csv
do
cp -v "$f" /app/file/Mainfiles/SOURCE.LIST/"${f%.csv}"
done
Please try below
search_dir="/app/file/Mainfiles"
for entry in "$search_dir"/*
do echo "$(basename $entry)" >> "/app/file/Mainfiles/SOURCE.LIST"
done

How to move files from subfolders to their parent directory (unix, terminal)

I have a folder structure like this:
A big parent folder named Photos. This folder contains 900+ subfolders named a_000, a_001, a_002 etc.
Each of those subfolders contain more subfolders, named dir_001, dir_002 etc. And each of those subfolders contain lots of pictures (with unique names).
I want to move all these pictures contained in the subdirectories of a_xxx inside a_xxx. (where xxx could be 001, 002 etc)
After looking in similar questions around, this is the closest solution I came up with:
for file in *; do
if [ -d $file ]; then
cd $file; mv * ./; cd ..;
fi
done
Another solution I got is doing a bash script:
#!/bin/bash
dir1="/path/to/photos/"
subs= `ls $dir1`
for i in $subs; do
mv $dir1/$i/*/* $dir1/$i/
done
Still, I'm missing something, can you help?
(Then it would be nice to discard the empty dir_yyy, but not much of a problem at the moment)
You could try the following bash script :
#!/bin/bash
#needed in case we have empty folders
shopt -s nullglob
#we must write the full path here (no ~ character)
target="/path/to/photos"
#we use a glob to list the folders. parsing the output of ls is baaaaaaaddd !!!!
#for every folder in our photo folder ...
for dir in "$target"/*/
do
#we list the subdirectories ...
for sub in "$dir"/*/
do
#and we move the content of the subdirectories to the parent
mv "$sub"/* "$dir"
#if you want to remove subdirectories once the copy is done, uncoment the next line
#rm -r "$sub"
done
done
Here is why you don't parse ls in bash
Make sure the directory where the files exist is correct (and complete) in the following script and try it:
#!/bin/bash
BigParentDir=Photos
for subdir in "$BigParentDir"/*/; do # Select the a_001, a_002 subdirs
for ssdir in "$subdir"/*/; do # Select dir_001, … sub-subdirs
for f in "$ssdir"/*; do # Select the files to move
if [[ -f $f ]]; do # if indeed are files
echo \
mv "$ssdir"/* "$subdir"/ # Move the files.
fi
done
done
done
No file will be moved, just printed. If you are sure the script does what you want, comment the echo line and run it "for real".
You can try this
#!/bin/bash
dir1="/path/to/photos/"
subs= `ls $dir1`
cp /dev/null /tmp/newscript.sh
for i in $subs; do
find $dir1/$i -type f -exec echo mv \'\{\}\' $dir1/$i \; >> /tmp/newscript.sh
done
then open /tmp/newscript.sh with an editor or less and see if looks like what you are trying to do.
if it does then execute it with sh -x /tmp/newscript.sh

Script to move files

I used a script to create sub-directories based on the file names of all my mp4 files. My files and newly created sub directories, of the same name, are located in the smae sub directory. Now I need a script to move the mp4 files into each of the files corresponding sub directories. I hope this makes sense. ex: I would like to move "crank (2006).mp4" to the sub directory named "crank (2006)". I have about 1200 of these files to move to their already created sub directories. Please help.
Removing the .mp4 suffix uses %% to delete the sub-string .mp4 from the end of the $f variable.
The mkdir statement ensures that the sub-directory does exist before the mv command.
for f in *.mp4
do
subdir="${f%%.mp4}"
mkdir -p "$subdir"
mv "$f" "$subdir"
done
mmv 'smae/*.mp4' 'smae/#1/#1.mp4'
This is much safer than (noddy) scripts as mmv will check for loops, name collisions, possible problems in the move before moving any file etc.
Following code will,
find the .mp4 files in current directory,
create sub-directories based on the file names of all mp4 files,
move each of the files to corresponding sub directories
for f in *.mp4; do path=$(ls $f | rev | cut -c 5- | rev); mkdir $path; mv $f $path/. ; done
Ex: if "crank (2006).mp4" is available into current directory than new sub directory named "crank (2006)" will be created into current directory and "crank (2006).mp4" file will be moved into that sub-directory.
NOTE: instead of "mv" you can also use "cp" for copy files

Shell Script to update the contents of a folder - 2

I wrote this piece of code this morning.
The idea is, a text file (new.txt) has the details about the directory structure and the files in the directory.
Read new.txt, create the same directory structure at a destination directory (here it is /tmp), copy the source files to the corresponding destination directory.
Script
clear
DEST_DIR=/tmp
for file in 'cat new.txt'
do
mkdir -p $file
touch $file
echo 'ls -ltr $file'
cp -rf $file $DEST_DIR
find . -name $file -type f
cp $file $DEST_DIR
done
Contents of new.txt
Test/test1/test1.txt
Test/test2/test2.txt
Test/test3/test3.txt
Test/test4/test4.txt
The issue is, it executes the code, creates the directory structure, but instead of creating it at the end, it creates directories named test1.txt, test2.txt, etc. I have no idea why this is happening.
Another question: For Turbo C, C++, there is an option to check the execution flow? Is there something available in Unix, Perl and shell scripting to check the execution flow?
The script creates these directories because you tell it to on the line mkdir -p $file. You have to extract the directory path from you filename. The standard command for this is dirname:
dir=`dirname "$file"`
mkdir -p -- "$dir"
To check the execution flow is to add set -x at the top of your script. This will cause all lines that are executed to be printed to stderr with "+ " in front of it.
you might want to try something like rsync

Resources