Get only the Filename using a Shell Script - shell

I'm trying to get an example working:
Here is what I'm trying to do:
a) There are 7 files in a folder with the name and timestamp appended.
Examples : Windows_<timestamp>.csv and Linux_<timestamp>.csv so on and so forth.
I want to first a) Move the files that I'm about to re-name to a new folder as is and then rename the current file.
I've tried looking at Rename multiple files by replacing a particular pattern in the filenames using a shell script but that script isn't working for me. I believe I have to modify something in there, but I cant seem to get it work.
Can anyone please help me? I'm really stuck here.
Thanks!

#!/bin/bash
# find all the files that are created today and end with an extension.
# a) First find all the files created today, and filter only the files we care about.
# b) Move all these files into a new folder.
# c) Iterate all the files in this new folder.
# d) Re-name all the files in the destination folder by replacing the _
sourceFolderName="/home/abhididdigi/Desktop/TADDM"
targetFolderName="/home/abhididdigi/Desktop/TADDM_ServiceNow/"
#find all the files created today and only the CSV ones.
find $sourceFolderName -type f -mtime 0 -name '*.csv'|
while read filename
do
# TODO: Find only those files that we care about
cp $filename $targetFolderName
done
#targetFileName=${filename%_*}|sed 's#.*/##';
#Rename the files now, removing the timestamp from underscore, so that it is ready to consume.
for filename in $targetFolderName*; do
mv -v "${filename}" ${filename%_*}.`echo "${filename}" | awk -F. '{print $2}'`
done

Related

Renaming multiple files - first by finding the files in a set of subdirectories and then matching file names to a list containing the new file names

I have a set of files that are organised across a large number of sub-directories, for example:
/Image/Square001/Data
/Image/Square002/Data
/Image/Square003/Data
and so on.
All the files within these directories have a similar type of name but have different numbers within the name.
Triangle_284852_Data_222844_222846_20220302_034926.tiff
Triangle_284908_Data_222841_222843_20220302_035350.tiff
Triangle_284908_Data_222845_222843_20220302_035350.tiff
I had like to rename all of these files to include another number. The correct number needed has already been appended to a given filename within a text file (temp_names.txt)
Triangle_284852_Data_222844_222846_20220302_034926_1.tiff
Triangle_284908_Data_222841_222843_20220302_035350_63.tiff
Triangle_284908_Data_222845_222843_20220302_035350_12.tiff
I am trying to write a bash script to rename the files in the directory to match those in temp_names.txt
I think I need to use the find command, set up a while loop for each file to be matched based on their similarity and be renamed, but I am having trouble getting this right.
In the past, I have used something like:
for file in ./Image/Square*/Data/*.tiff
do
read line
mv "${file}" "${line}"
done < temp_names.txt
When the files are all in the same sub-directory and are read in the same order as they appear in my text file. However, this is not the case for these files and I need a new approach. I have been trying some variants of starting like this:
find /Images/Square*/Data/ -type f -name .tiff |
while IFS= read -d '' file_name; do
But I am unsure whether I should be using rename or mv in the next line, how to match the common parts between the filename in the directory and in the text file, and then how to add a changeable string (the number at the end) to the file name.
This is a script to do your requirement:
#!/bin/bash
find . -type f -name "Triangle_*.tiff" -print0 | while IFS= read -r -d '' file
do
# extract the filename, without extension
filename=$(basename "${file%.*}")
# Find that in the temp_names.txt file
newfilename=$(grep "$filename" temp_names.txt)
# extract the path of the file
filepath=$(dirname "$file")
# rename the file
mv -v "$file" "$filepath/$newfilename"
done
The find is recursive, so it will handle all files.
From each file, remove its extension, then grep for the name in the list of new filenames.
Since the file could be in any sub-directory, the path is extracted from the file found by find.
The mv changes the name of the file to the new name, under the same directory as the original file.
I put option -v to the mv to get some log of what is done. But you can remove it if not required.

Script to automate moving files from multiple directories to newly created directories with the same suffix (not file extension)

I'm processing a large collection of born-digital materials for an archive but I'm being slowed down by the fact that I'm having to manually create directories and find and move files from multiple directories into newly created directories.
Problem: I have three directories containing three different types of content derived from different sources:
-disk_images -evidence_photos -document_scans
The disk images were created from CDs that come with cases and writing on the cases that need to be accessible and preserved for posterity so pictures have been taken of them and loaded into the evidence photos folder with a prefix and inventory number. Some CDs came with indexes on paper and have been scanned and OCR'd and loaded into the document scan folder with a prefix and an inventory number. Not all disk images have corresponding photos or scans so the inventory numbers in those folders are not linear.
I've been trying to think of ways to write a script that would look through each of these directories and move files with the same suffix (not extension) to newly created directories for each inventory number but his is way beyond my expertise. Any help would be much appreciated and I will be more than happy to clarify if need be.
examples of file names:
-disk_images/ahacd_001.iso
-evidence_photos/ahacd_case_001.jpg
-document_scans/ahacd_notes_001.pdf
Potential new directory name= ahacd_001
There all files with inventory number 001 would need to end up in ahacd_001
Bold= inventory number
Here is a squeleton of program to iterate through your 3 starting folders and split your file names:
for folder in `ls -d */` #list directories
do
echo "moving folder $folder"
ls $folder | while read file # list the files in the directory
do
echo $file
# split the file name with awk and get the first part ( 'ahacd' ) and the last ('002')
echo $file | awk -F '.' '{print $1}' |awk -F '_' '{print $1 "_" $NF}'
# when you are statisfied that your file splitting works...
mkdir folder # create your folder
move file # move the file
done
done
A few pointers to split the filenames :
Get last field using awk substr
First I would like to say that file or directory names starting with - is a bad idea even if it's allowed.
Test case:
mkdir -p /tmp/test/{-disk_images,-evidence_photos,-document_scans}
cd /tmp/test
touch -- "-disk_images/ahacd_001.iso" #create your three test files
touch -- "-evidence_photos/ahacd_case_001.jpg"
touch -- "-document_scans/ahacd_notes_001.pdf"
find -type f|perl -nlE \
'm{.*/(.*?)_(.*_)?(\d+)\.}&&say qq(mkdir -p target/$1_$3; mv "$_" target/$1_$3)'
...will not move the files, it just shows you what commands it thinks should be runned.
If those commands is what you want to be runned, then run them by adding |bash at the end of the same find|perl command:
find -type f|perl -nlE \
'm{.*/(.*?)_(.*_)?(\d+)\.}&&say qq(mkdir -p target/$1_$3; mv "$_" target/$1_$3)' \
| bash
find -ls #to see the result
All three files are now in the target/ahacd_001/ subfolder.

How do I add a string to the beginning of the name of a collection of files in another directory using shell

I have a bunch of .xml files in the folder project/reports. From the "project" folder, I need to prepend the string "TEST-" to every .xml file in the "reports" folder. I know each of the .xml files will start with the same string, and end with .xml, but I don't know the middle. How do I do this?
ie. Original file: constantfilename.xml, New file: TEST-constantfilename.xml
I can't hardcode the names of the test themselves, it just needs to be able to add the string to all files in the folder with the extension .xml. I have seen a lot of methods for renaming the files in the current folder like this:
for f in *.xml
do
mv "$f" "TEST-$f"
done
but I don't understand how I can apply this when I need to change them from another directory.
Any help would be greatly appreciated! And before anyone asks, no I cannot just navigate to that folder, it has to be from the "project" folder.
After a lot of googling I ended up doing this. It looks for the string constant I know is at the front of my file and replaces it with TEST-constant.
for f in project/reports/*.xml
do
a="$(echo $f | sed s/constant/TEST-constant/)"
mv "$f" "$a"
done
You could use the following one-liner (assuming you're on the project folder):
ls reports/*xml | awk -F '/' '{print "mv "$0" "$1"/TEST-"$2}' | sh
Is not as clean as yours, but it should give the same result.

Get full filepath while unzip in UNIX

I am stuck with one issue, and being a starter in shell script its getting confusing to achieve it.
I need to pull the file name while unzipping a file (which contains different file with different paths) in shell.
Example:
/java/server/test/Class1.java
/java/server/Xml1.xml
Output
I should get below as output in some local variables:
/java/server/test/
/java/server/
Note: I am using unzip utility for this.
If you'e got the full filename including path in $Filename then
${Filename##*/}
will give the path and
${Filename%/*}
will give the filename.
You can done this using combination of sed.
unzip a.zip | sed 's/.*: \(.*\)\/.*$/\1/'
It will give you the directory names without file names. If you need a uniq value, then use uniq command with that.
unzip a.zip | sed 's/.*: \(.*\)\/.*$/\1/' | uniq
Just unzip the file normally
unzip myfolder.zip
and then recurse through the folder and get the filepaths:
find $(pwd)/myfolder -type d
This last command gets (find) all folders (-type d) in extracted directory (myfolder) in the current directory (pwd).
Then you can redirect its output to a file
find $(pwd)/myfolder -type d > dirnames
or store it in a variable:
DIRNAMES=$(find $(pwd)/myfolder -type d)

Move and rename files based on subfolders

I would appreciate any help, relatively new here
I have the following directory structure
Main_dir
|-Barcode_subdirname_01\(many further subfolders)\filename.pdf
|-Barcode_subdirname_02\(many further subfolders)\filename.csv
There are 1000s of files within many subfolders
The first level sub directories have the barcode associated to all files within. eg 123456_dirname
I want to copy all files within all subfoders to the main_dir and
rename the files subdirname_barcode_filename.extension (based only on the first subdirectory name and barcode)
I've been attempting to write a bash script to do this from the main_dir but have hit the limit of my coding ability (i'm open to any other way that'll work).
firstly identifying the first level sub folders
find -maxdepth 1 -type d |
then cut out the first 2 parts deliminated by the underscores
cut -d\_ -f1 > barcode
then find the files within the subfolders, rename and move
find -type f -print0 |
while IFS= read -r filenames; do
newname="${barcode/sudirname/filename\/}"
mv "filename" "main_dir"/"newname"
done
I can't get it to work and may be headed in the wrong direction.
You can use rename with sed like substitute conventions, for example
$ rename 's~([^_]+)_([^_]+)_.*/([^/.]+\..*)~$1_$2_$3~' barcode_subdir_01/a/b/c/file2.csv
will rename file to
barcode_subdir_file2.csv
I used ~ instead of the more common / separator to make it more clear.
You can test the script with -n option to show the renamed files without actually doing the action.

Resources