Search code examples
macossedfile-rename

rename the end of filename by subtracting value


I have on macOS the following files in ns_up/ directory:

sqRatio_ist_LogSplineInterpPk_iz_260.dat
sqRatio_ist_LogSplineInterpPk_iz_261.dat
sqRatio_ist_LogSplineInterpPk_iz_262.dat
sqRatio_ist_LogSplineInterpPk_iz_263.dat
sqRatio_ist_LogSplineInterpPk_iz_264.dat
sqRatio_ist_LogSplineInterpPk_iz_265.dat
sqRatio_ist_LogSplineInterpPk_iz_266.dat
sqRatio_ist_LogSplineInterpPk_iz_267.dat
sqRatio_ist_LogSplineInterpPk_iz_268.dat
sqRatio_ist_LogSplineInterpPk_iz_269.dat
sqRatio_ist_LogSplineInterpPk_iz_270.dat
sqRatio_ist_LogSplineInterpPk_iz_271.dat
sqRatio_ist_LogSplineInterpPk_iz_272.dat
sqRatio_ist_LogSplineInterpPk_iz_273.dat
sqRatio_ist_LogSplineInterpPk_iz_274.dat
sqRatio_ist_LogSplineInterpPk_iz_275.dat
sqRatio_ist_LogSplineInterpPk_iz_276.dat
sqRatio_ist_LogSplineInterpPk_iz_277.dat
sqRatio_ist_LogSplineInterpPk_iz_278.dat
sqRatio_ist_LogSplineInterpPk_iz_279.dat
sqRatio_ist_LogSplineInterpPk_iz_280.dat
sqRatio_ist_LogSplineInterpPk_iz_281.dat
sqRatio_ist_LogSplineInterpPk_iz_282.dat
sqRatio_ist_LogSplineInterpPk_iz_283.dat
sqRatio_ist_LogSplineInterpPk_iz_284.dat
sqRatio_ist_LogSplineInterpPk_iz_285.dat
sqRatio_ist_LogSplineInterpPk_iz_286.dat
sqRatio_ist_LogSplineInterpPk_iz_287.dat
sqRatio_ist_LogSplineInterpPk_iz_288.dat
sqRatio_ist_LogSplineInterpPk_iz_289.dat
sqRatio_ist_LogSplineInterpPk_iz_290.dat
sqRatio_ist_LogSplineInterpPk_iz_291.dat
sqRatio_ist_LogSplineInterpPk_iz_292.dat
sqRatio_ist_LogSplineInterpPk_iz_293.dat
sqRatio_ist_LogSplineInterpPk_iz_294.dat
sqRatio_ist_LogSplineInterpPk_iz_295.dat
sqRatio_ist_LogSplineInterpPk_iz_296.dat
sqRatio_ist_LogSplineInterpPk_iz_297.dat
sqRatio_ist_LogSplineInterpPk_iz_298.dat
sqRatio_ist_LogSplineInterpPk_iz_299.dat

I would like to rename each of one by subtracting the value 200 at the end of the filename, for example :

sqRatio_ist_LogSplineInterpPk_iz_299.dat = sqRatio_ist_LogSplineInterpPk_iz_99.dat

I tried the following thing :

for i in $(ls ns_up/); do
  number=$(echo $i | gsed 's/\(.*\)_\(.*\).dat/\2/')
  new_number=$((number-200))
  echo $i | gsed 's/_\(.*\)\.dat/"\$new_number"\.dat/'
done

But unfortunately, this doesn't work and I don't know why.

Anyone would have an idea?


Solution

  • You can install (Perl) rename with homebrew using:

    brew install rename
    

    Then try:

    rename -n 's/(\d+)/$1 - 200/e' ns_up/*dat
    

    The -n says to do a "dry run", i.e. say what it would do, without actually doing anything.

    The Perl expression in single quotes, receives each filename in turn in variable $_ and is expected to modify it and return the new value in the same variable.

    The substitution says "substitute any bunch of adjacent digits it finds with that number minus 200."

    The e says to evaluate the right side of the substitution.

    This approach has some added benefits:

    • you can do a dry run easily
    • it will not clobber files if any two input filenames were to result in the same output filename
    • see man page for many more advantages