Page 1 of 2 12 LastLast
Results 1 to 15 of 16
  1. #1
    Join Date
    Sep 2003
    Posts
    23

    Unanswered: rename files in script

    Hello

    I need to do a simple script, but I do not manage to make it, my mind is blocked. I have several files in a directory, ejem:

    pepe.123
    pepe.124
    pepe.125

    and I need to change the name of these files inserting a letter ejem:

    pepe. G123
    pepe. G124
    pepe. G125

    I have to do this of automatic form whit all files in one script

    Please can anybody help me

  2. #2
    Join Date
    Aug 2001
    Location
    UK
    Posts
    4,650

    Re: rename files in script

    See if this helps :

    ls pepe* | while read fname
    do
    echo $fname | nawk '{dotindex=index($0,".") ; print substr($0,1,dotindex-1)".G"substr($0,dotindex+1)}' | read fnewname
    mv $fname $fnewname
    done


    Cheers
    Sathyaram


    Originally posted by sant
    Hello

    I need to do a simple script, but I do not manage to make it, my mind is blocked. I have several files in a directory, ejem:

    pepe.123
    pepe.124
    pepe.125

    and I need to change the name of these files inserting a letter ejem:

    pepe. G123
    pepe. G124
    pepe. G125

    I have to do this of automatic form whit all files in one script

    Please can anybody help me
    Visit the new-look IDUG Website , register to gain access to the excellent content.

  3. #3
    Join Date
    Sep 2003
    Posts
    23
    hello

    thank you to help me

    I have executed the script but it doesn´t work, I get the following error message:

    mv: a file is missed as argument
    mv: a file is missed as argument
    mv: a file is missed as argument

    my system is a linux, can you help me

    regards

  4. #4
    Join Date
    Jun 2003
    Location
    West Palm Beach, FL
    Posts
    2,713

    Lightbulb

    Better try this:

    Code:
    
    #!/bin/bash
    ls -1 pepe* |\
    while read f
    do
      mv $f ${f%.*}.G${f##*.}
    done
    
    The person who says it can't be done should not interrupt the person doing it. -- Chinese proverb

  5. #5
    Join Date
    Sep 2003
    Posts
    23

    Smile

    Now is OK

    Thank you, thank you very much

  6. #6
    Join Date
    May 2003
    Posts
    6

    Can you pls explain me this script line by line?

    Originally posted by LKBrwn_DBA
    Better try this:

    Code:
    
    #!/bin/bash
    ls -1 pepe* |\
    while read f
    do
      mv $f ${f%.*}.G${f##*.}
    done
    
    I need to do something similar to this, so please explain me the above piece of code so that I can write something like this.

    Thanks,

    Kavita Chhabria

  7. #7
    Join Date
    Jun 2002
    Location
    UK
    Posts
    525

    Re: Can you pls explain me this script line by line?

    The first line is saying to use the bash shell ( you can omit this line if you like and it will use your current shell ) ...

    #!/bin/bash

    The next line says list all files whose name begins with "pepe" (the -1 flag is saying to format the output to 1 file per row)

    ls -1 pepe* |\

    In the line above, the '|' character is 'piping' the results into the next command. Note that the '\' is 'escaping the end of line character - in some shells, commands piped into one another must not be over multiple lines.

    The next line sets up a 'while' construct between the following 'do' and 'done'. The loop will continue until the result of 'read' returns false. i.e. until all the lines 'piped' from the 'ls' command have been read.

    while read f

    The above line assigns the value it reads to a variable it is calling 'f'

    The following line appears complex but is simply using some built in features to manipulate the output for the value of 'f'.

    mv $f ${f%.*}.G${f##*.}

    $f = theFileName

    ${f%.*} = the value of theFileName after the SHORTest matching string has been removed from the RIGHT, following a '.'. The .* is used to match this, with the SINGLE % meaning - 'remove the shortest match from the right', e.g. 123.456.789 would become 123.456

    .G = the literal ".G"

    ${f##*.} = the value of theFileName after the LONGest matching string has been removed from the LEFT, preceding a '.'. The *. is used to match this, with the DOUBLE ## meaning - 'remove the longest match from the left', e.g. 123.456.789 would become 789

    Putting this together for the file '123.456.789' , you are saying

    mv 123.456.789 123.456.G789


    There are limitations with this script in that if the filename contains whitespace or newlines, it will fall over. This probably won't be the case but to get round it, quote your variables, e.g.

    mv "$f" "${f%.*}.G${f##*.}"

    Instead of using "while read", use for "f in *".

    for fileName in *
    do
    test -f "$fileName" && mv "$fileName" "${fileName%.*}.G${fileName##*.}"
    done

    In the above example, the shell will expand * to the filenames it finds in the current directory. The 'test -f &&' ensures that the filename is a file (as opposed to a directory) before attempting the move.

    HTH
    Last edited by Damian Ibbotson; 09-29-03 at 13:00.

  8. #8
    Join Date
    May 2003
    Posts
    6

    Re: Can you pls explain me this script line by line?

    Originally posted by Damian Ibbotson
    The first line is saying to use the bash shell ( you can omit this line if you like and it will use your current shell ) ...

    #!/bin/bash

    The next line says list all files whose name begins with "pepe" (the -1 flag is saying to format the output to 1 file per row)

    ls -1 pepe* |\

    In the line above, the '|' character is 'piping' the results into the next command. Note that the '\' is 'escaping the end of line character - in some shells, commands piped into one another must not be over multiple lines.

    The next line sets up a 'while' construct between the following 'do' and 'done'. The loop will continue until the result of 'read' returns false. i.e. until all the lines 'piped' from the 'ls' command have been read.

    while read f

    The above line assigns the value it reads to a variable it is calling 'f'

    The following line appears complex but is simply using some built in features to manipulate the output for the value of 'f'.

    mv $f ${f%.*}.G${f##*.}

    $f = theFileName

    ${f%.*} = the value of theFileName after the SHORTest matching string has been removed from the RIGHT, following a '.'. The .* is used to match this, with the SINGLE % meaning - 'remove the shortest match from the right', e.g. 123.456.789 would become 123.456

    .G = the literal ".G"

    ${f##*.} = the value of theFileName after the LONGest matching string has been removed from the LEFT, preceding a '.'. The *. is used to match this, with the DOUBLE ## meaning - 'remove the longest match from the left', e.g. 123.456.789 would become 789

    Putting this together for the file '123.456.789' , you are saying

    mv 123.456.789 123.456.G789


    There are limitations with this script in that if the filename contains whitespace or newlines, it will fall over. This probably won't be the case but to get round it, quote your variables, e.g.

    mv "$f" "${f%.*}.G${f##*.}"

    Instead of using "while read", use for "f in *".

    for fileName in *
    do
    test -f "$fileName" && mv "$fileName" "${fileName%.*}.G${fileName##*.}"
    done

    In the above example, the shell will expand * to the filenames it finds in the current directory. The 'test -f &&' ensures that the filename is a file (as opposed to a directory) before attempting the move.

    HTH
    Thanks a ton Damian for explaining everything so well.

    Can u pls help me with a script that is supposed to do the following:

    1. First the shell script needs to execute squid -k rotate on all the log files in a particular directory
    2. Then the script is supposed to find all files with the syntax "access_*"
    3. For each file found, we have to retain the .n extension of the file

    (for example, after running squid command, files will get extensions like log.0, log.1 etc),

    however, rename the file to have the following syntax "servername_yyyymmddhhmmss.n"

    4. Then after the file has been renamed compliant to the format described in step3, it has to be ftped to a particular server ( I know how to do this step, so I am okay on how to do this)

    5. Delete the yyyymmddhhmmss.n file from the original location since it has already been ftped.


    Hi, Damian, can you assist me to some extent with the above script, I hae not done shell scripting before, that's why, I am currently struggling with this task which I am sure might seem very trivial to you.

    Thanks a lot,

    Kavita Chhabria

  9. #9
    Join Date
    Jun 2002
    Location
    UK
    Posts
    525

    Re: Can you pls explain me this script line by line?


    1. First the shell script needs to execute squid -k rotate on all the log files in a particular directory
    2. Then the script is supposed to find all files with the syntax "access_*"
    3. For each file found, we have to retain the .n extension of the file

    (for example, after running squid command, files will get extensions like log.0, log.1 etc),

    however, rename the file to have the following syntax "servername_yyyymmddhhmmss.n"

    4. Then after the file has been renamed compliant to the format described in step3, it has to be ftped to a particular server ( I know how to do this step, so I am okay on how to do this)

    5. Delete the yyyymmddhhmmss.n file from the original location since it has already been ftped.
    You'll need to tell me a little more about squid. Does it create more than one output file for each input file?


    To generate a filename like 'servername_yyyymmddhhmmss.n',

    fileName=$(hostname)_$(date +%Y%m%d%H%M%S).n

    To find files that contain 'access_*' use,

    grep -l "access_\*" *

    Other than that, I probably need a little more info.
    Last edited by Damian Ibbotson; 09-29-03 at 14:09.

  10. #10
    Join Date
    May 2003
    Posts
    6
    Hi Damian:

    when squid -k rotate is exectued, what happens is that if there is a log file called access_servername.log, it rotates this file and renames it to access_servername.log.0 and if there already exists a access_servername.log.0 file, after the rotate command is executed, this file is rename to access_servername.log.1.

    So, in other words, what the rotate command does is that if the file ends with a .log extension, it appends a .0 after that and if the file ends with a .log.0 extension, it renames it to .log.1 and so on and so forth.

    I hope I have made it clear to you, if not, pls ask, I will try explaining it some other way.

    Also, why do you ask me to use grep -l "access_\*"* syxtax in order to look for files with the syntax "access_*", can't I simply use
    ls -1 access_*, just like u had used in your previous posting where u were searching for files starting with pepe followed by any sequence of characters.

    Thanks,

    Do ask more questions if u need to.

    Kavita Chhabria

  11. #11
    Join Date
    May 2003
    Posts
    6

    Re: Can you pls explain me this script line by line?

    Originally posted by Damian Ibbotson
    You'll need to tell me a little more about squid. Does it create more than one output file for each input file?


    To generate a filename like 'servername_yyyymmddhhmmss.n',

    fileName=$(hostname)_$(date +%Y%m%d%H%M%S).n

    To find files that contain 'access_*' use,

    grep -l "access_\*" *

    Other than that, I probably need a little more info.
    One more question for you Damian:

    Why do u put the hostname in brackets, why can't u simply say $hostname

    Also what does $(date + %Y%m%d%H%M%S) do, does it output the current date in the format that I was requesting, for example, will it give the current date as YYYYMMDDHHMMSS?

    Thanks,

    Kavita

  12. #12
    Join Date
    Jun 2002
    Location
    UK
    Posts
    525

    Also, why do you ask me to use grep -l "access_\*"* syxtax in order to look for files with the syntax "access_*", can't I simply use
    ls -1 access_*
    Sorry, I thought you meant files that *contain* the string "access_*" as opposed to filenames that *match* the string "access_*". In that case you could use 'ls'. Although, as I pointed out before, you would be better using...

    'for fileName in access_*'

    The above does away with the need for 'ls' as the shell will expand the * to match files in the current directory (it's part of shell command line processing known as 'globbing')

    I put 'hostname' in brackets because hostname is a command/utility not a variable. The $() construct around hostname causes the command to be executed and its standard output (i.e. theServerName) to be substituted.

    The same applies to $(date) but for your purposes you include some of date's formatting instructions to output the date in your required YYYYMMDDHHMMSS format.

    See what you can come up with and if you get stuck let me/us know.

  13. #13
    Join Date
    May 2003
    Posts
    6

    Having some difficulties with this script

    Hello Damian:

    Here is a very simple version of the script that I am currently trying out, but it is not working, I shall explain shortly, where exactly it is failing.

    $hostcurrdatetime=$(hostname)_$(date +%Y%m%d%H%M%S)
    for filename in access_*.log.*
    do
    test -f "$filename" && mv "$filename" "$hostcurrdatetime".${filename##*.}
    done

    It fails right at line 1, it provides me with the correct host name and then it does append the correct date and time and then prints out command not found.

    for example, it prints out servername_currentdatetime: command not found.

    It just stops there, can you please tell me what is it that I am doing wrong.

    Thanks,

    Kavita Chhabria

  14. #14
    Join Date
    Jun 2002
    Location
    UK
    Posts
    525
    Get rid of the $ at the very beginning.

    You use a $ to reference a variable but not when you define it.

  15. #15
    Join Date
    May 2003
    Posts
    6
    Originally posted by Damian Ibbotson
    Get rid of the $ at the very beginning.

    You use a $ to reference a variable but not when you define it.
    Hello Damian:

    Thanks a lot for all your help on this script. I do have it working now, however, I have one more requirement to be added to the script.

    What is currently happening is that squid -k rotate command creates an empty log file if there is none in the log folder. I was not aware of this behavior of squid -k rotate command.

    So, what I would like to do is to check the size of the file and if it is empty, then I do not want to rename it and compress it and them ftp it over etc etc as you are aware, how do we do that in linux, I am already using the test -f filename command within my script to check if it is a file or not and then doing all the remaining steps. I would like to add this additional check of seeing if the file is empty or not as well?

    Thanks so much,

    Kavita Chhabria

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •