Renaming files in a folder to sequential numbers
Try to use a loop, let
, and printf
for the padding:
a=1
for i in *.jpg; do
new=$(printf "%04d.jpg" "$a") #04 pad to length of 4
mv -i -- "$i" "$new"
let a=a+1
done
using the -i
flag prevents automatically overwriting existing files, and using --
prevents mv
from interpreting filenames with dashes as options.
Bash change filenames from month name to month number
Assuming you have the GNU version of date(1), you could use date -d
to map the month names to numbers:
for f in *.pdf; do
IFS=- read y m d <<<"${f%.pdf}"
mv "$f" "$(date -d "$m $d, $y" +%F.pdf)"
done
I doubt it's any more efficient than your sed -e 's/January/01/' -e 's/February/02/'
etc, but it does feel less tedious to type. :)
Explanation:
Loop over the .pdf files, setting
f
to each filename in turn.The
read
line is best explained right to left:
a."${f%.pdf}"
expands to the filename without the.pdf
part, e.g. "2020-August-15".
b.<<<
turns that value into a here-string, which is a mechanism for feeding a string as standard input to some command. Essentially,x <<<y
does the same thing asecho y | x
, with the important difference that thex
command is run in the current shell instead of a subshell, so it can have side effects like setting variables.
c.read
is a shell builtin that by default reads a single line of input and assigns it to one or more shell variables.
d. IFS is a parameter that tells the shell how to split lines up into words. Here we're setting it – only for the duration of theread
command – to-
. That tellsread
to split the line it reads on hyphens instead of whitespace;IFS=- read y m d <<<"2020-August-15"
assigns "2020" toy
, "August" tom
, and "15" tod
.The GNU version of date(1) has a
-d
parameter that tells it to display another date instead of the current one. It accepts a number of different formats itself, sadly not including "yyyy-Mon-dd", which is why I had to split the filename up withread
. But it does accept "Mon dd, yyyy", so that's what I pass to it.+%F.pdf
tells it that when it prints the date back out it should do so ISO-style as "yyyy-mm-dd", and append ".pdf" to the result. ("%F" is short for "%Y-%m-%d"; I could also have used-I
instead of+
anything and moved the.pdf
outside the command expansion.)
f. The call todate
is wrapped in$(...)
to capture its output, and that result is used as the second parameter tomv
to rename the files.
How to rename files in bash to increase number in name?
If you can get hold of the Perl-flavoured version of rename
, that is simple like this:
rename -n 's/(\d+)/$1 + 100/e' *fasta
Sample Output
'Ciprianus_maximus_11_fred.fasta' would be renamed to 'Ciprianus_maximus_111_fred.fasta'
'Ciprianus_maximus_300_fred.fasta' would be renamed to 'Ciprianus_maximus_400_fred.fasta'
'Ciprianus_maximus_3900_fred.fasta' would be renamed to 'Ciprianus_maximus_4000_fred.fasta'
If you can't read Perl, that says... "Do a single substitution as follows. Wherever you see a bunch of digits next to each other in a row (\d+
), remember them (because I put that in parentheses), and then replace them with the evaluated expression of that bunch of digits ($1
) plus 100.".
Remove the -n
if the dry-run looks correct. The only "tricky part" is the use of e
at the end of the substitution which means evaluate the expression in the substitution - or I call it a "calculated replacement".
Rename files with incrementing number starting at certain number
This should work:
for f in *.ABC; do
num=$(basename "$f" .ABC)
num2=$(printf "%05d" $((num + 55)))
echo mv "$f" "$num2.ABC"
done
Notes:
I am assuming your files all follow the pattern of digits followed by
.ABC
, so thatbasename $f .ABC
extracts the number. You'll have to adjust thenum=
line if this assumption does not hold.$(( ... ))
is thebash
syntax to do arithmetic operations.(printf "%05d" ...)
is here to pad zeroes in front of the number, otherwise you'd just get55
etc.Remove the
echo
once you're convinced it's doing the right thing.EDIT Warning: the new set of filenames should not overlap the old set of filenames, or you might lose some files. Carefully choosing the order the
mv
commands are run could solve the issue, but putting the files in a new directory as they are renamed and moving them back after would be much simpler.
EDIT:
@MarkSetchell pointed out in the comments that you want sequential numbering that is not based on the original file names, in which case this loop would work instead:
i=55 # choose your starting destination file number here
for f in *.ABC; do
dest=$(printf "%05d" $i).ABC
echo mv "$f" "$dest"
i=$((i + 1))
done
Is it possible to change a number of filenames to be the file extension in bash?
One solution is to use a for loop to cycle through the files beginning with "$FILENAME", e.g.
for f in "$FILENAME"*
do
mv "$f" "${f##*.}"
done
Or, as a one-liner:
for f in "$FILENAME"*; do mv "$f" "${f##*.}"; done
Bash script to rename files and increment number in the file name by N
This should work
filename=$1 #Filename
filenumber=$2 #file number from where you want to rename.
count=$3 #number of files
lastfile=$4 #Last filenumber in the folder
for ((i=lastfile; i>=$filenumber; i--))
do
mv $filename$i $filename`expr $i + $count`
done
You can run it like below
./rename wizard 15 3 30
Replace numbers in a file name in unix (BASH)
Most probably this one could be fine :)
# printf is used to emulate a lot of files
for f in $( printf "company_red%03d.p12\n" {1..150} )
do
# get the filename
n="$f"
# remove extension
n="${n%.*}"
# remove leading letters
n="${n##*[[:alpha:]]}"
# add 24, 10# is used to consider the 10-based number
n="$(( 10#$n + 24 ))"
# construct new filename
g="red${n}.p12"
echo mv "$f" "$g"
done
And this could be simplified a bit
for f in $( printf "company_red%03d.p12\n" {1..150} )
do
# take the number from the specific, fixed position
n="${f:11:3}"
# everything below is the same as in the previous example
n="$(( 10#$n + 24 ))"
g="red${n}.p12"
echo mv "$f" "$g"
done
And finally, this could be simplified yet twice -- just escape of using $n
and $g
:
for f in $( printf "company_red%03d.p12\n" {1..150} )
do
echo mv "$f" "red$(( 10#${f:11:3} + 24 )).p12"
done
But this could complicate understanding and supporting of the code.
Related Topics
Using $Origin to Specify the Interpreter in Elf Binaries Isn't Working
Any Reason for Using "*/" in Command "Ls -D */" to List Directories
How to Solve "Bash: Ls: Command Not Found"
How Can a Program Detect If It Is Running as a Systemd Daemon
Perf_Event_Open Always Returns -1
Is an Operating System Kernel an Interpeter for All Other Programs
How to Get Gcc to Skip Errors, But Still Output Them
Combine Two CSV Files Based on Common Column Using Awk or Sed
How to Hide Password from Jenkins Shell Output
Displaying or Redirecting a Shell's Job Control Messages
Are the 'Dot' and 'Dot Dot' Files in Unix and Linux Real Files
How to Make a Bash String of Command with Redirect and Pipe
How to Scale Ejabberd Server MAChine on Centos to Handle 200 K Connections
Wget: Unsupported Scheme on Non-Http Url
Converting a Visual Studio Makefile to a Linux Makefile
Find Command Find Directories That Were Created After a Certain Date Under Linux/Cygwin