remove substring from filename - shell

I have files with name of the form "NAME-xxxxxx.tedx" and I want to remove the "-xxxxxx" part. The x are all digits.
The regex "\-[0-9]{1,6}" matches the substring, but I have no idea how to remove it from the filename.
Any idea how I can do that in the shell?

If you have the perl version of the rename command installed, you could try:
rename 's/-[0-9]+//' *.tedx
Demo:
[me#home]$ ls
hello-123.tedx world-23456.tedx
[me#home]$ rename 's/-[0-9]+//' *.tedx
[me#home]$ ls
hello.tedx world.tedx
This command is smart enough to not rename files if it means overwriting an existing file:
[me#home]$ ls
hello-123.tedx world-123.tedx world-23456.tedx
[me#home]$ rename 's/-[0-9]+//' *.tedx
world-23456.tedx not renamed: world.tedx already exists
[me#home]$ ls
hello.tedx world-23456.tedx world.tedx

echo NAME-12345.tedx | sed "s/-[0-9]*//g"
will give NAME.tedx. So you can use a loop and move the files using mv command:
for file in *.tedx; do
newfile=$(echo "$file" | sed "s/-[0-9]*//g")
mv "$file" $newfile
done

If you want to use just the shell
shopt -s extglob
for f in *-+([0-9]]).tedx; do
newname=${f%-*}.tedx # strip off the dash and all following chars
[[ -f $newname ]] || mv "$f" "$newname"
done

Related

Change basename of multiple files in a single directory

I have many files of the form {a}_{b}_R1.txt I would like to change the basenames of these files to {a}.{b}.txt how would I go about this? I can only find out how to do this with extensions. Thanks.
You can just a simple loop in the native bash shell under OS X from terminal, after navigating to the folder containing those text files,
# Looping for all the text files in the current
# directory
for file in *.txt; do
# Stripping off '_R1' from the file-name
temp1="${file//_R1/}"
# Replacing '_' with '.' and renaming the file to the name generated
temp2="${temp1//_/.}"
echo "$temp2" "$file"
#mv -v "$file" "$temp2"
done
Remove the line with echo and uncomment the mv once you find the names are changed accordingly.
for file in *.txt; do temp1="${file//_R1/}"; temp2="${temp1//_/.}"; mv -v "$file" "$temp2"; done
This works as well:
for f in *.txt; do mv "$f" "echo $f | sed s/_R1//"; done then for f in *.txt; do mv "$f" "echo $f | sed s/_/./";

Bash script to remove chars from all filenames in folder

I have a folder with few images, all have the same name format:
some-random-name-min.jpg
another-random-name-min.jpg
and-another-random-name-min.jpg
I want to strip the last -min so following this answer
I tried this bash script:
#!/bin/bash
for filename in /home/al/domus-images/portfolio/white snow/*.jpg; do
mv $filname $(echo $filename | sed -e 's/....\.jpg$//');
done
but after running the script nothing happened..any idea what am I missing here?
Thanks
You can use find command to list the files and then to remove -min from file name follow below script.
for filename in `find "/home/al/domus-images/portfolio/white snow/" -name "*.jpg"`;
do
mv $filname $(echo $filename | sed 's/-min.jpg$/.jpg/');
done
This remove last "-min" from file name.
this could be an idea:
#!/bin/bash
for filename in *\-min.jpg
do
newFile=$(echo $filename |sed "s/\-min//g")
printf "before\t:filename[$filename]\tnewFile[$newFile]\n"
mv $filename $newFile
printf "after\t:filename[$filename]\tnewFile[$newFile]\n"
done
output
[shell] ➤ ./myMove
before :filename[and-another-random-name-min.jpg] newFile[and-another-random-name.jpg]
after :filename[and-another-random-name-min.jpg] newFile[and-another-random-name.jpg]
before :filename[another-random-name-min.jpg] newFile[another-random-name.jpg]
after :filename[another-random-name-min.jpg] newFile[another-random-name.jpg]
before :filename[some-random-name-min.jpg] newFile[some-random-name.jpg]
after :filename[some-random-name-min.jpg] newFile[some-random-name.jpg]
this *\-min.jpg is just to be sure to get only the file you need
This might be what you're looking for
#!/bin/bash
for filename in /home/al/domus-images/portfolio/white snow/*-min.jpg
do
mv ${filename} ${filename//-min.jpg/.jpg}
done
Can't get it simpler than this.
rename 's/\-min.jpg$/.jpg/' *-min.jpg

How to rename some file of same pattern in shell scripting

I want to write a code is shell scripting which will rename all the files of extension .txt in a current directory to extension .c .Suppose my current directory contains some 100 .txt file. This number is not fixed.
for f in *.txt; do echo mv "$f" "${f%.txt}.c"; done
Remove "echo" when you're satisfied it's working. See the bash manual for the meaning of "%" here.
See man rename. You can rename multiple files providing regexp substitution.
rename 's/\.txt$/.c/' *.txt
If you don't have rename in you system, you can use find:
find . -name '*.txt' | while read FILE; do echo mv "$FILE" "$(echo "$FILE" | sed 's/\.txt$/.c/g')"; done
Remove echo when you verify it does what you want.
awk can do this trick too:
kent$ ls *.txt|awk '{o=$0;gsub(/txt$/,"c"); print "mv "o" "$0;}'|sh

Batch renaming using shell script

I have a folder with files named as
input (1).txt
input (2).txt
input (3).txt
...
input (207).txt
How do I rename them to
input_1.in
input_2.in
input_3.in
...
input_207.in
I am trying this
for f in *.txt ; do mv $f `echo $f | sed -e 's/input\ (\(\d*\))\.txt/input_\1.in/'` ; done
But it gives me
mv: target `(100).txt' is not a directory
mv: target `(101).txt' is not a directory
mv: target `(102).txt' is not a directory
...
Where did I go wrong?
I have put in the quotes now, but I get this now
mv: `input (90).txt' and `input (90).txt' are the same file
It is somehow trying to rename the file to the same name. How is that happening?
That is because bash for split the element with space ' ' so you are commanding it to move 'input' to '(1)'.
The way to solve this is to tell bash to split by new line using IFS variable.
Like this:
IFS=$'\n'
Then do your command.
However, I suggest you to use find to do this instead using -exec command.
For example:
find *.txt -exec mv "{}" `echo "{}" | sed -e 's/input\ (\([0-9]*\))\.txt/input_\1.in/'` \;
NOTE: I write this from memory and I did test this so let try and adjust it.
Hope this helps.
You're forgetting to quote your arguments.
... mv "$f" "$(echo "$f" | ... )" ; done
no need to call external commands
#!/bin/bash
shopt -s nullglob
shopt -s extglob
for file in *.txt
do
newfile="${file//[)]/}"
newfile="${file// [(]/_}"
mv "$file" "${newfile%.txt}.in"
done
As you've already fixed, you need to quote the $f argument to mv.
As to your second problem, sed doesn't support \d. You could use [0-9] instead.
for f in *.txt ; do mv "$f" `echo $f | sed -e 's/input\ (\(\d*\))\.txt/input_\1.in/'` ; done
If you have GNU Parallel http://www.gnu.org/software/parallel/ installed you can do this:
seq 1 207 | parallel -q mv 'input ({}).txt' input_{}.in
Watch the intro video for GNU Parallel to learn more:
http://www.youtube.com/watch?v=OpaiGYxkSuQ

Bash command to remove leading zeros from all file names

I have a directory with a bunch of files with names like:
001234.jpg
001235.jpg
004729342.jpg
I want to remove the leading zeros from all file names, so I'd be left with:
1234.jpg
1235.jpg
4729342.jpg
I've been trying different configurations of sed, but I can't find the proper syntax. Is there an easy way to list all files in the directory, pipe it through sed, and either move or copy them to the new file name without the leading zeros?
for FILE in `ls`; do mv $FILE `echo $FILE | sed -e 's:^0*::'`; done
sed by itself is the wrong tool for this: you need to use some shell scripting as well.
Check Rename multiple files with Linux page for some ideas. One of the ideas suggested is to use the rename perl script:
rename 's/^0*//' *.jpg
In Bash, which is likely to be your default login shell, no external commands are necessary.
shopt -s extglob
for i in 0*[^0]; do mv "$i" "${i##*(0)}"; done
Maybe not the most elegant but it will work.
for i in 0*
do
mv "${i}" "`expr "${i}" : '0*\(.*\)'`"
done
Try using sed, e.g.:
sed -e 's:^0*::'
Complete loop:
for f in `ls`; do
mv $f $(echo $f | sed -e 's:^0*::')
done
I dont know sed at all but you can get a listing by using find:
find -type f -name *.jpg
so with the other answer it might look like
find . -type f -name *.jpg | sed -e 's:^0*::'
but i dont know if that sed command holds up or not.
Here's one that doesn't require sed:
for x in *.jpg ; do let num="10#${x%%.jpg}"; mv $x ${num}.jpg ; done
Note that this ONLY works when the filenames are all numbers. You could also remove the leading zeros using the shell:
for a in *.jpg ; do dest=${a/*(0)/} ; mv $a $dest ; done
In Bash shell you can do:
shopt -s nullglob
for file in 0*.jpg
do
echo mv "$file" "${file##*0}"
done

Resources