After copying bash directory, edit filenames in new directoy? - linux

I'm currently working on a problem in bash shell to copy a directory to a new one, and that when you check that new directory it will have changed the names of the files it copied. Not sure how to word it exactly so I'll show what it is supposed to output:
-------$ ls -a myproject/
./ ../ file1 file2.c file3.txt .this_is_a_hidden_file
-------$ bkup myproject mybackup
-------$ ls -a mybackup
./ ../ file1-BACKUP file2-BACKUP.c file3-BACKUP.txt
So what happens is that my second parameter in the script bkup copies what is in the first parameter, then edits the names of the files of parameter #1 to add "-BACKUP" between the stem and the extension (eg. between file2 and .c to make file2-BACKUP.c)
I have figured out how to copy the directories using cp -a sourceDir./ destinationDir but how would I edit the file names within destinationDir? Any help is appreciated! Thanks.

Use rename command to rename multiple files using regex, try below
# change directory to the destination folder
$ cd destinationDir
# rename all files
# -n flag will only display how files will be renamed
# once satisfied then remove the -n flag from below command and it will actually rename all files
$ rename -n -v 's/(.+?)(\.[^.]*$|$)/$1-BACKUP$2/' *
You can parameterize the command and include this in your script (bkup)
I am not in front of my Linux box .. so please test and let me know if you see any error.

Related

How to copy over all files from one directory to another excluding ones that start with a given string in a bash script

I have a directory containing a large amount of files ~1gb. I need to copy over all of them except ones that start with "name" to a different directory. I tried using this: "ls src_folder | grep -v '^name' | xargs cp -t dest_folder" from this pervious question In Linux, how to copy all the files not starting with a given string?
I get the following error when trying to copy over test1.txt from src_folder which contains test1.txt and name.txt to dest_folder
cp: cannot stat `test1.txt': No such file or directory
My current work around is to copy over all of the files, then use find to delete the ones starting with "name" in the dest_folder. This works, but I imagine I could save some time by only copying over the files I really want. Any suggestions?
You can use the shell option extglob. This option extends the bash's pattern matching, so you can use more advanced expressions.
shopt -s extglob
cp src_folder/!(name*) dest_folder
For more info run nam bash and look for extglob.

Is there a grep command that allows me to grep multiple folders and copy them using a text file containing the file names

So I have a text file containing the names of ~1000 folder names, and a directory with around ~30,000 folders. What I need to do is to find a bash command that will read the text file for the folder names, and grep those folders from the directory and copy them to a new destination. Is this at all possible?
I am new to coding, my apologies if this isn't worded well.
you can use a bash scrit like this one:
fileList=$(cat nameFIle)
srcDir="/home/ex/src"
destDir="/home/ex/dest"
for name in fileList
do
cp -r "${srcDir}/${name}" "${destDir}"/
done
Definitely possible - and you don't even need grep. Assuming your text file has one file per line.
cp -r `cat filenames.txt` path_to_copy_location/
I would write:
xargs cp -t /destination/directory < file.of.dirnames

Adding text into a created file

I'll try and explain my issue as easy as possible.
I have made a script which unzips a file and then takes the data from the resulting files and sorts them into appropriate folders. I am now struggling with one specific part.
My script needs to output a file that contains a label for each directory and the files need to be sorted in reversible order. So far I have this:
#firstly changes to correct directory and then creates a file that contains a list of all the files in that directory sorted by size order
cd processFiles/$type1
ls -S > orderSize1.txt
cd ../$type2
ls -S > orderSize2.txt
cd ../$type3
ls -S > orderSize3.txt
cd ../misc
ls -S > orderSize4.txt
#lists file types by reverse alphabetical order
cd ../$type1
ls -r > tempfile1.txt
cd ../$type2
ls -r > tempfile2.txt
cd ../$type3
ls -r > tempfile3.txt
cd ../misc
ls -r > tempfile4.txt
So in the file I need to have it listed reverse alphabetically (which is done in my script already) but how do I put in comments saying 'these are the jpg files' or 'these are all the gif files.'?
I also need to write a separate clean up script for this, but I think that is quite easy - not too sure on it though.
Thanks for your help!
This assumes you're using bash. Other shells may do things a little differently.
As karakfa noted in a comment, you can use the echo command along with redirection to print a message to a file. For example:
echo "These are the jpeg files." > jpegfiles.txt
Then, when you run your ls command, you would use append redirection to add the results to the file:
ls -r >> jpegfiles.txt

Move files from one dir to another and add to each files name in the new directory

I need to move each *.lis file in its current directory to a new directory and add to the file's existing filename for an application to pickup the file with the new name.
For example:
Move /u01/vista/vmfiles/CompressGens.lis and /u01/vista/vmfiles/DeleteOnline.lis
to
/u01/vista/Migration_Logs/LIS.BHM.P.MIGRATION_LOGS.FBA."$(date '+%m%d%y%H%M%S')"CompressGens.lis
and
/u01/vista/Migration_Logs/LIS.BHM.P.MIGRATION_LOGS.FBA."$(date '+%m%d%y%H%M%S')"DeleteOnline.lis
What I started out with in my script:
cp -f /u01/vista/vmfiles/*.lis /u01/vista/Migration_Logs/LIS.BHM.P.MIGRATION_LOGS.FBA."$(date '+%m%d%y%H%M%S')"*.lis
There are multiple *.lis in the /u01/vista/vmfiles/ directory, and depending on the system and day, the *.lis files will not always be the same. Sometimes it is "DeleteOnline.lis" and CompressGens.lis but not ArchiveGens.lis. Then the next day will be CompressGens.lis and ArchiveGens.lis.
So I will need to get the *.lis filenames in the /u01/vista/vmfiles/ directory, and then move each one.
You need a loop, so that you can do one file at a time.
ls -1tr *.lis | while read File
do
cp -p $File ../Migration_Logs/${File%.lis}.$(date '+%m%d%y%H%M%S').CompressGens.lis &&
mv $File ../Migration_Logs/${File%.lis}.$(date '+%m%d%y%H%M%S').DeleteOnline.lis
done
${File%.lis} is the bash/korn means of stripping that suffix - see ksh or bash man page.
The "&&" idiom is in order only to mv the file to the 2nd archived name if the copy for the 1st archived file works.
#Abe Crabtree, Thanks for the help in pointing me in the right direction. Below is the final code that worked.
ls -1tr *.lis | while read File
do
mv $File /u01/vista/Migration_Logs/LIS.BHM.P.MIGRATION_LOGS.FBA.$(date '+%m%d%y%H%M%S').${File%.lis}.lis
done

output to a file in script directory

This probably quite basic but I have spent whole day finding an answer without much success.
I have an executable script that resides in ~/Desktop/shell/myScript.sh
I want a single line command to run this script from my terminal that outputs to a new directory in same directory where the script is located no matter what my present working directory is.
I was using:
mkdir -p tmp &&
./Desktop/shell/myScript.sh|grep '18x18'|cut -d":" -f1 > tmp/myList.txt
But it creates new directory in present working directory and not on the target location.
Any help would be appreciated.
Thanks!
You could solve it in one line if you pre-define a variable:
export LOC=$HOME/Desktop/shell
Then you can say
mkdir -p $LOC/tmp && $LOC/myScript.sh | grep '18x18' | cut -d":" -f1 > $LOC/tmp/myList.txt
But if you're doing this repeatedly it might be better long-term to wrap myScript.sh so that it creates the directory, and redirects the output, for you. The grep and cut parameters, as well as the output file name, would be passed as command-line arguments and options to the wrapper.
How about this:
SCRIPTDIR="./Desktop/shell/" ; mkdir "$SCRIPTDIR/tmp" ; "$SCRIPTDIR/myScript.sh" | grep '18x18' | cut -d ":" -f 1 > "$SCRIPTDIR/tmp/myList.txt"
In your case you have to give the path to the script anyway. If you put the script in the path where it is automatically searched, e.g. $HOME/bin, and you can just type myScript.sh without the directory prefix, you can use SCRIPTDIR=$( dirname $( which myScript.sh ) ).
Mixing directories with binaries and data files is usually a bad idea. For temporary files /tmp is the place to go. Consider that your script might become famous and get installed by the administrator in /usr/bin and run by several people at the same time. For this reason, try to think mktemp.
YOUR SCRIPT CAN DO THIS FOR YOU WITH SOME CODES
Instead of doing this manually from the command line and who knows where you will move your script and put it. add the following codes
[1] Find your script directory location using dirname
script_directory=`dirname $0`
The above code will find your script directory and save it in a variable.
[2] Create your "tmp" folder in your script directory
mkdir "$script_directory/tmp 2> /dev/null"
The above code will make a directory called "tmp" in your script directory. If the directory exist, mkdir will not overwrite any existing directory using this command line and gave an error. I hide all errors by "2> /dev/null"
[3] Open your script and modify it using "cut" and then redirect the output to a new file
cat "$0"|grep '18x18'|cut -d":" -f1 > "$script_directory"/tmp/myList.txt

Resources