Rename multiple .txt files changing some characters in specific positions
Rename multiple .txt files changing some characters in specific positions
I have a collections of hundreds of .txt files in the same folder in Ubuntu 16.04, and they're named with strings and index numbers, like that:
a01_s01_e01_skeleton.txt
a01_s01_e02_skeleton.txt
a01_s01_e03_skeleton.txt
a01_s02_e01_skeleton.txt
...
a20_s10_e02_skeleton.txt
...
I must remove the 0 (zeros) from every .txt file where the number is smaller than 10, so in the end I'll have:
instead of : a01_s01_e01_skeleton.txt
it will be: a1_s1_e1_skeleton.txt #notice that the 0s are gone.
EDIT
The position of the numbers is always the same, like in the examples. The files have a logic of order, so the renaming process must be totally correct.
How could I do that using the command line?
The position of the numbers in the string is always the same.
– Elisa Maria Alves
Aug 30 at 16:10
Have you tried anything for yourself? Or are you expecting us to write this for you?
– j-money
Aug 30 at 16:41
5 Answers
5
Ok, just for fun, no doubt there are shorter cli solutions, but in python, the script below does the job if the directory is "flat" (as you say) and all files in it are valid files to rename. If not, we need to add an exception, so here we go:
import shutil
import sys
import os
dr = sys.argv[1]
for f in os.listdir(dr):
sections = f.split("_")
newname = "_".join(
[s[0] + str(int(s[1:])) for s in sections[:3]] + [sections[-1]]
)
shutil.move(os.path.join(dr, f), os.path.join(dr, newname))
rename_stuff.py
Run it with the directory as argument:
python3 /path/to/rename_stuff.py </directory/with/files>
As always, first try on a sample directory.
Read the files in the directory:
for f in os.listdir(dr):
Split the name by "_":
sections = f.split("_")
On the first three sections, replace the two (or more) -digit number by its int- ("real") value, so 01 -> 1, 10 -> 10, 020 -> 20, 000300 -> 300 and so on.
Subsequently, glue the sections together again:
newname = "_".join(
[s[0] + str(int(s[1:])) for s in sections[:3]] + [sections[-1]]
)
With the perl rename
, you can remove zeroes that occur between a non-digit and a digit.
rename
$ touch a01_s01_e01_skeleton.txt a01_s01_e02_skeleton.txt a01_s01_e03_skeleton.txt a01_s02_e01_skeleton.txt a20_s10_e02_skeleton.txt
$ rename -n 's/(?<=D)0+(?=d)//g' *.txt
rename(a01_s01_e01_skeleton.txt, a1_s1_e1_skeleton.txt)
rename(a01_s01_e02_skeleton.txt, a1_s1_e2_skeleton.txt)
rename(a01_s01_e03_skeleton.txt, a1_s1_e3_skeleton.txt)
rename(a01_s02_e01_skeleton.txt, a1_s2_e1_skeleton.txt)
rename(a20_s10_e02_skeleton.txt, a20_s10_e2_skeleton.txt)
rename
may or may not be the perl version. On my system it is called file-rename
and it has an alternatives symlink as /usr/bin/rename
rename
file-rename
/usr/bin/rename
Using rename
alias rename.ul
installed from the package util-linux, I made the following bash shellscript, that I think can do the job for you.
rename
rename.ul
#!/bin/bash
#####################
doer ()
# removes "0" from the string "parameter0"
# for example a0 --> a
rename "s/$10/$1/" *
#####################
# main
#####################
doer a
doer s
doer e
Let us call the shellscript renamer
and give it execute permissions.
renamer
If zeros to be removed are preceded by other letters than a,s,e, please add a call of doer
with those letters into the script and modify the shellscript, if there are instances, not shown by your sample file names, which need more details in the substitute specification (the function doer
).
doer
doer
Create and check 'original' files
$ touch a01_s01_e01_skeleton.txt a01_s01_e02_skeleton.txt a01_s01_e03_skeleton.txt a01_s02_e01_skeleton.txt a20_s10_e02_skeleton.txt
$ ls -1
a01_s01_e01_skeleton.txt
a01_s01_e02_skeleton.txt
a01_s01_e03_skeleton.txt
a01_s02_e01_skeleton.txt
a20_s10_e02_skeleton.txt
renamer
Run the shellscript
$ ./renamer
Check the result
$ ls -1
a1_s1_e1_skeleton.txt
a1_s1_e2_skeleton.txt
a1_s1_e3_skeleton.txt
a1_s2_e1_skeleton.txt
a20_s10_e2_skeleton.txt
renamer
$
why not change your regex to include all your alpha arguments and only run the function once (without any arguments)? Or better yet, just skip defining the function.
rename "s/[ase]0/$1/" *
all by itself does the trick.– Dennis Williamson
Aug 30 at 21:39
rename "s/[ase]0/$1/" *
@DennisWilliamson, The command that you suggest does not work for me. I could change my regex to something more complicated or difficult to understand, but if my current script solves the problem of the OP, why make it more complicated? (There is no indication from the OP yet, which answer is preferred for the real case.)
– sudodus
Aug 31 at 4:43
Sorry I missed that you were also using the argument on the right hand side. You could simply change the whole thing to use capture groups.
– Dennis Williamson
Aug 31 at 12:58
Sorry in advance, but I've never worked with shellscript bash files before, and I'm confused about where to save the rename.ul file and how to make it run through the command line.
– Elisa Maria Alves
Aug 31 at 14:42
@ElisaMariaAlves,
rename
alias rename-ul
comes with the package util-linux, which is normally installed by default in Ubuntu. So you need not worry about installing it. I mentioned it because there are other rename
programs, that might work differently. So it runs when called (by the command line with it) as described in my answer. -- But I understand that you prefer another answer, which is OK for me. That answer is a good one. -- Good luck :-)– sudodus
Aug 31 at 15:24
rename
rename-ul
rename
Perl's rename utility is the best option for this, I think.
rename 's/(w)0(d)/$1$2/g' *.txt
This command will replace all occurrences of a letter followed by a zero followed by a digit, retaining the letter and the digit while discarding the zero, for every text file in the current directory.
Using zsh:
autoload zmv
zmv 'a(<->)_s(<->)_e(<->)_skeleton.txt' 'a$1#0_s$2#0_e$3#0_skeleton.txt'
I do not get it
– Pierre.Vriens
Aug 31 at 4:21
Welcome to Ask Ubuntu :-) Please edit your answer and provide a bit more information on how your command works as a ton of people don't get it (bash is the standard) and then your answer is likely to be deleted because of "low quality" even though it's 100% correct. ¯_(ツ)_/¯
– Fabby
Aug 31 at 23:35
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Useful additional info would be if the position of the numbers in the string is always the same or not, and if possible dupes might occur after renaming. If so, what do do then.
– Jacob Vlijm
Aug 30 at 16:05