Inserting characters in the file name

I have a directory with a bunch of files called (for example)

how it is:            how it should be:
945TITLE-1.txt        945TITLE-00.txt
945TITLE-10.txt       945TITLE-01.txt
945TITLE-2.txt        945TITLE-02.txt
945TITLE-23.txt       945TITLE-03.txt
945TITLE-3.txt        945TITLE-10.txt
945TITLE.txt          945TITLE-23.txt

      

The numbers and text that cause the dash character can change, so they must be variable. Ignoring the unnumbered file (945TITLE.txt in this case) I use the following line to grab all files that end with a dash and one digit

file=`ls -1 working/pages/files | grep [-][0-9].txt`

      

But now I can't figure out how to splicate 0 between a dash and a digit.

for file in $filelist
do  
????
done

      

After several attempts I got further development:

for file in working/pages/files/$filelist
do  
f1=${filelist%%[-]*}
f2=${filelist##*[-]}
finalName=${f1}-0${f2}
echo $finalName
mv $file working/pages/files/$finalName
done

      

The output is for $finalName

always 945TITLE-03.txt

, and it only applies the command mv

to 945TITLE-1.txt

(incorrectly changing it to 945TITLE-03.txt

) and stating that she cannot find other files (since she only looked at the folder working/pages/files/

for the first file)

Any help would be much appreciated and I am by no means married to this solution, so if you can think of a more elegant one other than what I suggest, I would be more than happy to hear it. Thanks you

+3


source to share


4 answers


Here's a simple example I made here based on where you started. There 945TITLE.txt

is some funny special case for your case :



#!/bin/bash

for file in 945*
do
    suffix=${file##*[.]}
    base=$(basename ${file} .${suffix})
    prefix=${base%%[-]*}
    number=${base##*[-]}
    case ${number} in
        ''|*[!0-9]*) number=0 ;;
    esac
    echo ${prefix}-$(printf "%02d" ${number}).${suffix}
done

      

0


source


Idea:



  • The process is executed line by line (example 945TITLE-1.txt)
  • First divide by "-" (which gives "945TITLE" and "1.txt")
  • Then split the second pin of the first split by "." (which gives "1" and "txt")

    ls -1 | awk '{ 
             n=split($0, array , "-");
             if( n > 1 ) {
               printf("%s-",array[1]);
               split(array[2],arraydot,".");
               printf("%02d.%s\n", arraydot[1], arraydot[2]);
              } else {
               split(array[1],arraydot, "."); 
               printf("%s-00.%s\n",arraydot[1],arraydot[2]);
             }
          }' | sort
    
          

    The other condition above handles the case for 945TITLE.txt

0


source


this awk-onliner will work: (you can remove completion first |sh

to check the generated mv commands.)

ls -[your options] |awk  -F'-|\\.' 'NF<3{x=$0;sub(/\./,"-00.",x)}NF>2{x=sprintf ("%s-%02d.%s",$1,$2,$3)}{print "mv "$0" "x}' |sh

      

I am simulating it with a text file.

kent$  cat test.txt
945TITLE-1.txt
945TITLE-10.txt
945TITLE-2.txt
945TITLE-23.txt
945TITLE-3.txt
945TITLE.txt

kent$  awk  -F'-|\\.' 'NF<3{x=$0;sub(/\./,"-00.",x)}NF>2{x=sprintf ("%s-%02d.%s",$1,$2,$3)}{print "mv "$0" "x}' test.txt
mv 945TITLE-1.txt 945TITLE-01.txt
mv 945TITLE-10.txt 945TITLE-10.txt
mv 945TITLE-2.txt 945TITLE-02.txt
mv 945TITLE-23.txt 945TITLE-23.txt
mv 945TITLE-3.txt 945TITLE-03.txt
mv 945TITLE.txt 945TITLE-00.txt

      

if you pipe the result to sh, for example awk.....|sh

, this mv command will be executed.

0


source


Here's a Perl example that might work for you:

perl -E 'while(<*.txt>){ $a = $_; s/-\K\d\./0$&/ || s/\D\K\./-00./; rename $a, $_; }'

      

Not tested tho .; -)

0


source







All Articles