How to uppercase file name but exclude extension - linux

Is it possible to use rename to uppercase a file but exclude its extension?
ie:
I want to rename the file foo_bar.ext to FOO_BAR.ext
I tried with rename 'y/a-z/A-Z/' foo_bar.ext, but the whole file (including extension) gets uppercased FOO_BAR.EXT

You are asking rename to convert all the instances of [a-z] to [A-Z]. Instead, capture the desired string into a group and modify it:
rename 's/([^.]*)/\U$1/' foo_bar.ext
This would rename the file foo_bar.ext to FOO_BAR.ext.
If you have a file foo_bar.baz.ext that needs to be renamed to FOO_BAR.BAZ.ext, use greedy match and multiple groups. Saying:
rename 's/(.*)(\..*)/\U$1\E$2/' foo_bar.baz.ext
would rename the file foo_bar.baz.ext to FOO_BAR.BAZ.ext.

You can use positive lookahead:
rename 's/.+(?=\.)/\U$&/g' *
Example:
$ ls
input.foo.bar.txt
$ rename 's/.+(?=\.)/\U$&/g' *
$ ls
INPUT.FOO.BAR.txt

Related

How to copy multiple files with varying version numbers from one directory to another using bash?

I have a folder /home/user/Document/filepath where I have three files namely file1-1.1.0.txt, file2-1.1.1.txt, file3-1.1.2.txt
and another folder named /home/user/Document/backuppath where I have to move files from /home/user/Document/folderpath which has file1-1.0.0.txt, file2-1.0.1.txt and file3-1.0.2.txt
task is to copy the specific files from folder path to backup path.
To summarize:
the below is the files.txt where I listed the files which has to be copied:
file1-*.txt
file2-*.txt
The below is the move.sh script that execute the movements
for file in `cat files.txt`; do cp "/home/user/Document/folderpath/$file" "/home/user/Documents/backuppath/" ; done
for the above script I am getting the error like
cp: cannot stat '/home/user/Document/folderpath/file1-*.txt': No such file or directory found
cp: cannot stat '/home/user/Document/folderpath/file2-*.txt': No such file or directory found
what I would like to accomplish is that I would like to use the script to copy specific files using * in the place of version numbers., since the version number may vary in the future.
You have wildcard characters in your files.txt. In your cp command, you are using quotes. These quotes prevent the wildcards to be expanded, as you can clearly see from the error message.
One obvious possibility is to not use quotes:
cp /home/user/Document/folderpath/$file /home/user/Documents/backuppath/
Or not use a loop at all:
cp $(<files.txt) /home/user/Documents/backuppath/
However, this would of course break if one line in your files.txt is a filename pattern which contains white spaces. Therefore, I would recommend a second loop over the expanded pattern:
while read file # Puts the next line into 'file'
do
for f in $file # This expands the pattern in 'file'
do
cp "/home/user/Document/folderpath/$f" /home/user/Documents/backuppath
done
done < files.txt

renaming multiple sequential files extension

I have multiple sequential files naming in one directory with multiple incremental files extension. My objective is using rename command to rename just the file extension.
IBM0020.DAT_001
IBM0020.DAT_002
IBM0020.DAT_003
IBM0021.DAT_001
IBM0021.DAT_002
IBM0022.DAT_001
IBM0022.DAT_002
IBM0022.DAT_003
IBM0022.DAT_004
...
to
IBM0020.DAT_001
IBM0020.DAT_002
IBM0020.DAT_003
IBM0021.DAT_004
IBM0021.DAT_005
IBM0022.DAT_006
IBM0022.DAT_007
IBM0022.DAT_008
IBM0022.DAT_009
...
I have dry run the command below, but not the expected result. I want to retain the filename and only rename/change the extension with running number sequence.
rename -n 's/.+/our $i;sprintf(".DAT_%03d",1+$i++)/e' *
IBM0020.DAT_001 renamed as .DAT_001
IBM0020.DAT_002 renamed as .DAT_002
IBM0020.DAT_003 renamed as .DAT_003
IBM0021.DAT_001 renamed as .DAT_004
IBM0021.DAT_002 renamed as .DAT_005
IBM0022.DAT_001 renamed as .DAT_006
IBM0022.DAT_002 renamed as .DAT_007
IBM0022.DAT_003 renamed as .DAT_008
IBM0022.DAT_004 renamed as .DAT_009
Thanks for any help.
Continuing from the comment, if all of your files have .DAT_XXX as the extension you wish to rename sequentially, then there is no need to include ".DAT_" as part of the pattern you are matching. Simply match the 3-digits at the end of the filename and change those, e.g.
rename 's/\d{3}$/our $i; sprintf("%03d", 1+$i++)/e' *
If ".DAT_" isn't unique, and you have other extensions ending in 3-digits you want to avoid renaming, then you can include "DAT_" as part of the pattern matched and replaced, e.g.
rename -n 's/DAT_\d{3}/our $i; sprintf("DAT_%03d", 1+$i++)/e' *
(note: there are two different "rename" utilities in common use on Linux, the first provided as part of the util-linux package does not support regex renaming, and then perl-rename, which you have, that does support perl-regex renaming.)

How to specify the tar final structure

I have this structure:
release/folder1/file1
release/folder2/file2
...
release/folderN/fileN
I want to include all those folders (folder1, folder2 ... folderN) in a tar file.
The key is that I want these folders to be in the final tar within another directory named MYAPP so when you open the tar you can see this:
MYAPP/folder1/file1
MYAPP/folder2/file2
...
MYAPP/folderN/fileN
How can I achieve this without renaming the original "release" directory and/or creating new directories.
Is this possible to achive just in the tar process?
Thanks
Add
--transform=s#^release/#MYAPP/#
to your tar command line.
The argument of the --transform command line is a command that is passed to sed together with the file path before it is stored in the archive (use tar -tf to show the names of the files stored in the archive).
The command s#^release/#MYAPP/# tells sed to search (s) release/ at the beginning of the string (^) and replace it with MYAPP/.
The / at the end of the search and replace strings is needed to be sure the complete name of the component is release (to not replace release.txt). The # character is just a regex delimiter. Usually / is used as a regex delimiter but we prefer to use a different delimiter here to avoid the need to escape / (because it is used in the search and replace strings).
Read more in the documentation of tar and sed.

Batch renaming filenames between hyphens using bash

I'm a student and I'm very new to bash, so any help is greatly appreciated!
I'm trying to rename a batch of files that look like this: local_date_1415+6556_0001.txt and local_date_1415+6556_0002.txt.
Example file name: uuw_07052006_1415+6556_0001.txt
I need the "1415+6556" section of each filename to have a 2M in front of it, like "2M1415+6556". About half the files in the folder already have the 2M, so I can't just search for the string and replace.
Is there a way to rename the batch of files using "_" as a delimiter so I could replace all the third sections entirely with the correct string?
I have the rename command on my machine, I'm just not sure how to use it here.
Using your version of rename:
rename _ % *_????+*.txt # replace the first underscore with a percent
rename _ _2M *_????+*.txt # add 2M after the second underscore
rename % _ *_2M????+*.txt # return the first underscore back
Only works if your filenames don't contain %. If they do, pick a different character.
You can also write the loop yourself:
#! /bin/bash
for f in *_????+*.txt ; do
before=${f%[0-9][0-9][0-9][0-9]+*}
after=${f#*_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]}
mv "$f" "$before"2M"$after"
done

Script shell for renaming and rearranging files

I would like to rearrange and rename files.
I have this tree structure of files :
ada/rda/0.05/alpha1_freeSurface.md
ada/rda/0.05/p_freeSurface.md
ada/rda/0.05/U_freeSurface.md
ada/rda/0.1/alpha1_freeSurface.md
ada/rda/0.1/p_freeSurface.md
ada/rda/0.1/U_freeSurface.md
I want that files will be renamed and rearranged like this structure below:
ada/rda/ada-0.05-alpha1.md
ada/rda/ada-0.05-p.md
ada/rda/ada-0.05-U.md
ada/rda/ada-0.1-alpha1.md
ada/rda/ada-0.1-p.md
ada/rda/ada-0.1-U.md
Using the perl rename (sometimes called prename) utility:
rename 's|ada/rda/([^/]*)/([^_]*).*|ada/rda/ada-$1-$2.md|' ada/rda/*/*
(Note: by default, some distributions install a rename command from the util-linux package. This command is incompatible. If you have such a distribution, see if the perl version is available under the name prename.)
How it works
rename takes a perl commands as an argument. Here the argument consists of a single substitute command. The new name for the file is found from applying the substitute command to the old name. This allows us not only to give the file a new name but also a new directory as above.
In more detail, the substitute command looks like s|old|new|. In our case, old is ada/rda/([^/]*)/([^_]*).*. This captures the number in group 1 and the beginning of the filename (the part before the first _) in group 2. The new part is ada/rda/ada-$1-$2.md. This creates the new file name using the two captured groups.
You can use basename and dirname functions to reconstruct the new filename:
get_new_name()
{
oldname=$1
prefix=$(basename $oldname _freeSurface.md)
dname=$(dirname $oldname)
basedir=$(dirname $dname)
dname=$(basename $dname)
echo "$basedir/ada-$dname-$prefix.md"
}
e.g. get_new_name("ada/rda/0.05/alpha1_freeSurface.md") will show ada/rda/ada-0.05-alpha1.md in console.
Then, you can loop through all your files and use mv command to rename the files.

Resources