3

The inputfile is,

test00.dat test07.dat test03.dat
aram22.dat test09.dat aram09.dat
test13.dat

I need the output file as

test01.dat test08.dat test04.dat
aram22.dat test10.dat aram09.dat
test14.dat

i.e. the numerical string associated with test is increased by unity. I need a suitable terminal command-line to perform this operation.

Especially, I need to know the conversion mechanism of 'test09.dat' to 'test10.dat' change.

7
  • Per-file or in a directory? Recursively or "flat"? – Jacob Vlijm Mar 30 '15 at 8:08
  • In a single 'input.txt' file all strings are written and I need the output written in the mentioned manner in 'output.txt' file. It will be more convenient if I can do it in recursive manner. For example, from test00.dat to test99.dat. – tamal Mar 30 '15 at 8:18
  • I see, you mean text inside a file. – Jacob Vlijm Mar 30 '15 at 8:22
  • Do all searched strings end with .dat (that would limit the search)? – Jacob Vlijm Mar 30 '15 at 8:23
  • Yes, text inside a file. All strings end with .dat – tamal Mar 30 '15 at 8:25
2

You can use the following perl oneliner to do the transformation:

echo "test00.dat test09.dat aram22.dat" | perl -pe 's/test\K(\d+)/sprintf "%02d", $1+1/eg'

Result:

test01.dat test10.dat aram22.dat

To use your input file:

$ perl -pe 's/test\K(\d+)/sprintf "%02d", $1+1/eg' your_file
test01.dat test08.dat test04.dat
aram22.dat test10.dat aram09.dat
test14.dat
0

Here you're a bash solution:

#!/bin/bash

if [ ! -f "$1" ]; then
    echo "File not found!"
    exit
fi

names=$(cat "$1" | sort)

for i in $names; do
    filename=${i%.*}
    extension=${i##*.}
    number=${filename: -2:2}
    name=${filename//[0-9]}
    fnumber=$(printf "%02d\n" $((${number#0}+1)))
    if [[ "$name" == "test" ]]; then
        echo "${name}${fnumber}.${extension}"
    else
        echo "$i"
    fi    
done
2
  • Unfortunately your script does not preserve the expected output. Moreover it seems that OP only wants test.*dat to be incremented, not aram.*.dat – Sylvain Pineau Mar 30 '15 at 10:13
  • Solved, I don't read the original purpose of the question. I thought that it should increment a unit on all filenames. – 0x2b3bfa0 Mar 30 '15 at 11:07
0

The script below assumes the numbers in the words occur consecutively in the filenames (e.g. file_123.dat, not file12something345.dat), and the names of the files are unique.

What it does

  • It searches the file for words with integers in the name.
  • It will convert those (consecutive) integers int "real" integers (values), which will remove the leading zeros.
  • Add one to the value
  • Then compare the "original" length of the number-string with the edited value, adding leading zeros if the edited string is shorter.

Example:

test999.dat test07.dat test03.dat
aram22.dat test09.dat aram09.dat
test0000013.dat

outputs:

test1000.dat test08.dat test04.dat
aram22.dat test10.dat aram09.dat
test0000014.dat

The script

#!/usr/bin/env python3
import sys

file = open(sys.argv[1]).read()
for w in [w for w in file.split() if w.startswith("test")]:
    try:
        found = "".join([ch for ch in w if ch.isdigit()])
        replace = (len(found), str(int(found)+1))
        file = file.replace(w, w.replace(found, replace[1].zfill(replace[0])))
    except ValueError:
        pass
print(file.strip())

How to use

  1. Copy it into an empty file, save it as add_one.py
  2. Run it with the file as an argument by the command:

    python3 /path/to/add_one.py '</path/to/file>`
    
0
0

A quick'n'dirty solution based on How to find and replace a particular string by increasing its numerical part?

echo "test00.dat test07.dat aram22.dat" | perl -pe 's/(?<=test)(\d+)/$1+1/eg' | sed -e 's/test\([0-9]\)\./test0\1/g'
test01dat test08dat aram22.dat

Note that there is an ugly hack in my command: perl outputs test1.dat and I use sed to fix it to test01.dat

Not the answer you're looking for? Browse other questions tagged or ask your own question.