user3720427
user3720427

Reputation: 81

A script to change file names

I am new to awk and shell based programming. I have a bunch of files name file_0001.dat, file_0002.dat......file_1000.dat. I want to change the file names such as the number after file_ will be a multiple of 4 in comparison to previous file name. SO i want to change

file_0001.dat to file_0004.dat
file_0002.dat to file_0008.dat 

and so on.

Can anyone suggest a simple script to do it. I have tried the following but without any success.

#!/bin/bash
a=$(echo $1 sed -e 's:file_::g' -e 's:.dat::g')
b=$(echo "${a}*4" | bc)
shuf file_${a}.dat > file_${b}.dat

Upvotes: 8

Views: 581

Answers (6)

potong
potong

Reputation: 58420

This might work for you:

paste <(seq -f'mv file_%04g.dat' 1000) <(seq -f'file_%04g.dat' 4 4 4000) | 
sort -r | 
sh

Upvotes: 1

Hongbo Liu
Hongbo Liu

Reputation: 3064

ls -r1 | awk -F '[_.]' '{printf "%s %s_%04d.%s\n", $0, $1, 4*$2, $3}' | xargs -n2 mv

  1. ls -r1 list file in reverse order to avoid conflict
  2. the second part will generate new filename. For example: file_0002.dat will become file_0002.dat file_0008.dat
  3. xargs -n2 will pass two arguments every time to mv

Upvotes: 1

perreal
perreal

Reputation: 97948

Using bash/sed/find:

files=$(find -name 'file_*.dat' | sort -r)
for file in $files; do
    n=$(sed 's/[^_]*_0*\([^.]*\).*/\1/' <<< "$file")
    let n*=4
    nfile=$(printf "file_%04d.dat" "$n")
    mv "$file" "$nfile"
done

Upvotes: 1

Conner
Conner

Reputation: 31060

Here's a pure bash way of doing it (without bc, rename or sed).

#!/bin/bash

for i in $(ls -r *.dat); do
   prefix="${i%%_*}_"
   oldnum="${i//[^0-9]/}"
   newnum="$(printf "%04d" $(( 10#$oldnum * 4 )))"
   mv "$i" "${prefix}${newnum}.dat"
done

To test it you can do

mkdir tmp && cd $_
touch file_{0001..1000}.dat
(paste code into convert.sh)
chmod +x convert.sh
./convert.sh

Upvotes: 1

Jacek Sokolowski
Jacek Sokolowski

Reputation: 597

This script will do that trick for you:

#!/bin/bash
for i in `ls -r *.dat`; do
    a=`echo $i | sed 's/file_//g' | sed 's/\.dat//g'`
    almost_b=`bc -l <<< "$a*4"`
    b=`printf "%04d" $almost_b`
    rename "s/$a/$b/g" $i
done

Files before:

file_0001.dat file_0002.dat

Files after first execution:

file_0004.dat file_0008.dat

Files after second execution:

file_0016.dat file_0032.dat

Upvotes: 2

klerk
klerk

Reputation: 371

This can help:

#!/bin/bash
for i in `cat /path/to/requestedfiles |grep -o '[0-9]*'`; do
   count=`bc -l <<< "$i*4"`
   echo $count
done

Upvotes: -1

Related Questions