I am trying to rename files which are in the schema A_B_x.csv, where x is in (1..10), what I want is to exactly have A_B_x 10.csv, e.g. if the file was A_B_1.csv I would like to have A_B_11.csv. I am pretty new to bash and have not found a solution, I tried:
for f in *.csv;
do
newname=`echo $f | sed 's/1.csv/11.csv/g'`;
mv $f $newname;
done
which replaces all 1's with 11's, but I am not sure how to generalize it so it works for all numbers. Does someone has an idea?
CodePudding user response:
Would you please try the following:
for f in *.csv; do
num=$(( ${f//[^0-9]} 10 ))
mv "$f" "$(sed -E 's/([^0-9] )[0-9] (. )/\1'"$num"'\2/' <<< "$f")"
done
${f//[^0-9]}
extracts digits from the variable$f
num=$(( ${f//[^0-9]} 10 ))
assigns num to the digits 10.- "$(sed -E 's/([^0-9] )[0-9] (. )/\1'"$num"'\2/' <<< "$f")" returns the
file name with the number substituted by
$num
.
[Alternative]
If the perl rename
command is available, you can also say:
rename 's/(\d )/$& 10/e' *.csv
Please note there are two different rename
commands.
CodePudding user response:
You don't need sed
for this (but of course you can use it). With only bash:
pre="${f%_*}"
tmp="${f##*_}"
num="${tmp%.csv}"
new="${pre}_$((num 10)).csv"
CodePudding user response:
You can do it quite simply with the bash builtin Parameter Expansions. You first trim the extension from the filename with fn="${j%.csv}"
. Save the base filename without the number as base="${j%_*}"
. Save the extension with ext="${j##*.}"
, and finally isolate the number with num="${fn##*_}"
Now just add 10
to the number, num=$((num 10))
and put the filename back together, new="${base}_${num}.${ext}"
and then move j
to new
.
You can do that as:
for j in A_B*; do
fn="${j%.csv}" ## filename w/o extension
base="${j%_*}" ## base filename w/o number
ext="${j##*.}" ## save extension
num="${fn##*_}" ## isolate number
num=$((num 10)) ## add 10 to number
new="${base}_${num}.${ext}" ## reconstitute filename w/new number
echo "$j -> $new" ## output result
# mv "$j" "$new" ## **Uncomment** to actually perform the move
done
Bash provides many, many useful parameter expansions, the set relevant to trimming from the front (beginning) and back (end) of a string are:
${var#pattern} Strip shortest match of pattern from front of $var
${var##pattern} Strip longest match of pattern from front of $var
${var%pattern} Strip shortest match of pattern from back of $var
${var%%pattern} Strip longest match of pattern from back of $var
(note: pattern can contain the normal globbing characters such as '*'
)
Example Use/Output
If you had filenames A_B_1.csv
to A_B_5.csv
in the current directory, the result would be:
A_B_11.csv
A_B_12.csv
A_B_13.csv
A_B_14.csv
A_B_15.csv