3

I files which a system generates with a generic file name. I want to have a script I can run which scans these files for the second instance of the word ProcID (after the word ProcID is a number) and then renames the file with the ProcID number. Currently I have the following:

FILEPATH; awk -F '[:)]' '/ProcID./{printf "mv %s %s.txt\n", FILENAME, $2 | "/bin/sh"; nextfile}' O*.TXT

For example, script scans files and finds second instance of (ProcID:0000014778) and then it renames the file with this Proc ID number.

The script above finds only the first instance, and therefore files are being renamed before the system has finished outputting to the file.

12
  • Do you need to set the extension, or just the id? Any risk on dupe names to take into account? Jan 27, 2017 at 16:59
  • Hi IanG, just curious, but did you notice the answer(s)? Jan 28, 2017 at 16:06
  • 2
    Can you explain why no python? You asked I want to have a script. If one or more languages are excluded, please add it to your question. Jan 30, 2017 at 11:34
  • 2
    Both Python 2 and Python 3 are widely used today, including for system administration, so you might want to install Python 3. It shouldn't interfere with your Python 2 installation (if any) at all. I think every Ubuntu system has at least one of python-minimal or python3-minimal preinstalled, though I'm unsure if this is universally true on Ubuntu Core. Either way, you should be able to get a fully functional Python 3 installation by installing the python3 package, for example by running sudo apt-get update and then sudo apt-get install python3. Jan 30, 2017 at 13:23
  • 1
    @IanG Python 2.4 is ancient (2003-2006) and is indicative that you're on an ancient (and long-unsupported) version of Ubuntu, or something else entirely, similarly crusty. For things to be answerable by our users —and useful to future users— we require you're using a supported version of Ubuntu and all the shiny things that come with it. We occasionally look the other way, but if you really are on something that old, a base prerequisite to any answer you get is going to be upgrading.
    – Oli
    Jan 30, 2017 at 16:42

2 Answers 2

5

The script below renames all files in a directory, to the id in the second found string, starting with ProcID::

1. Renaming to the id in the second matching string (literally; no extension)

enter image description here

#!/usr/bin/env python3
import shutil
import os
import sys

dr = sys.argv[1]

for f in os.listdir(dr):
    file = os.path.join(dr, f)
    try:
        # only rename if the second instance exists
        new = [s for s in open(file).read().split() if s.startswith("(ProcID:")][1]
    except (IndexError, IsADirectoryError):
        pass
    else:
        # rename the file
        shutil.move(file, os.path.join(dr, new.split(":")[-1].strip()[:-1]))

To use

  1. Copy the script into an empty file, save it as rename_files.py
  2. run it with the directory as argument:

    python3 /path/to/rename_files.py /path/to/directory_with_files
    

Notes

  • The script assumes the (exact) format: ProcID:0000014778
  • The script will not rename files if there is no second instance of ProcID (or none at all)

2. Only rename .txt files, and keep the extension

...Then use the version below, it will only rename .txt files and keep the extension in the renamed file. Usage is exactly the same.

#!/usr/bin/env python3
import shutil
import os
import sys

dr = sys.argv[1]

for f in os.listdir(dr):
    file = os.path.join(dr, f)
    try:
        # only rename is the second instance exists
        new = [s for s in open(file).read().split() if all([
            s.startswith("(ProcID:"), f.endswith(".txt")
            ])][1]
    except (IndexError, IsADirectoryError):
        pass
    else:
        shutil.move(file, os.path.join(dr, new.split(":")[-1].strip()[:-1]+".txt"))

What the script does

  • it lists the files in the directory:

    for f in os.listdir(dr)
    
  • lists the strings inside the file, starting with ProcID:

    new = [s for s in open(file).read().split() if s.startswith("(ProcID:")][1]
    

    The ending [1] extracts the second occurrence of strings, starting with ProcID: ([0] is the first one)

  • splits of the id:

    new.split(":")[-1].strip()
    
  • and renames the file, using the id:

    shutil.move(file, os.path.join(dr, new.split(":")[-1].strip()[:-1]))
    

EDIT

Python2 version of script 1. OP turns out to have python2 installed, which requires IOError instead of IsADirectoryError to prevent errors in case the script runs into a directory instead of a file.

#!/usr/bin/env python
import shutil
import os
import sys

dr = sys.argv[1]

for f in os.listdir(dr):
    file = os.path.join(dr, f)
    try:
        # only rename if the second instance exists
        new = [s for s in open(file).read().split() if s.startswith("(ProcID:")][1]
    except (IndexError, IOError):
        pass
    else:
        # rename the file
        shutil.move(file, os.path.join(dr, new.split(":")[-1].strip()[:-1]))

...and for being complete, a python2 version of the second script:

#!/usr/bin/env python
import shutil
import os
import sys

dr = sys.argv[1]

for f in os.listdir(dr):
    file = os.path.join(dr, f)
    try:
        # only rename is the second instance exists
        new = [s for s in open(file).read().split() if all([
            s.startswith("(ProcID:"), f.endswith(".txt")
            ])][1]
    except (IndexError, IOError):
        pass
    else:
        shutil.move(file, os.path.join(dr, new.split(":")[-1].strip()+".txt"))
6
  • Ran: python2 /PATH/rename_files.py /PATH/TO/DIRECTORY_WITH_FILES seems to run, but no change to the file names.
    – user633715
    Jan 30, 2017 at 14:34
  • Then could you give me the content of one of the files (just the relevant strings)? There must be an issue with that, else the files are renamed for sure. Jan 30, 2017 at 14:35
  • Here is an example: UCXJLI3M Version 6.00A patchlevel 907-602 JOB 42349166 (ProcID:0000027096) START AT 30.01.2017 / 10:00:02 ** UTC TIME 30.01.2017 / 10:00:02 TEXT=" Job started 0042346870 PROCESSNAME JOBNAME /PATH/TO/JOB ********************************************************************* **** UCXJLI3M Version 6.00A patchlevel 907-602 **** ** JOB 42349166 (ProcID:0000014778) ENDED AT 30.01.2017 / 10:00:03 ** ** UTC TIME 30.01.2017 / 10:00:03 ** ** TEXT=" Job ended " RETCODE=00 **
    – user633715
    Jan 30, 2017 at 14:39
  • Yep, got it, will edit. Done, please try again. Wait, still need to edit out ). Not sure if I'll make it... need to teach in a minute. Jan 30, 2017 at 14:40
  • Traceback (most recent call last): File "/PATH/rename_files.py", line 12, in ? new = [s for s in open(file).read().split() if all([ NameError: name 'all' is not defined
    – user633715
    Jan 30, 2017 at 15:34
2

Your original script was kind of close, and it can be edited to count the instances via if statement and a counter variable:

FILEPATH; awk -F '[:)]' '/ProcID./{ count++; if(count == 2 ){ printf "mv %s %s.txt\n", FILENAME, $2 | "/bin/sh"; nextfile}}' O*.TXT

In case you're seeking alternative solution, you could use this Perl script:

#!/usr/bin/env perl
use strict;
use warnings;

my $cnt=0;
open(my $fh,'<',$ARGV[0]) or die "open failed";
my $new_name;
while ( my $line = <$fh> ){
    $cnt+=1 if $line =~ /ProcID/;
    if($cnt==2){
        chomp $line;
        my @words = split(/[:)]/,$line); 
        $new_name = $words[1] . ".TXT";
        last;
    }
}
if (defined $new_name){
   rename $ARGV[0], $new_name;
}
close($fh)

Sample run:

$ ls
0000014777.TXT  rename_by_procid.pl*

$ ./rename_by_procid.pl 0000014777.TXT                                                                                                

$ ls
0000014778.TXT  rename_by_procid.pl*
1
  • HI. Thanks for this. I tried the following, which does work, but only does one file in a directory, it does not search all files and change. FILEPATH; awk -F '[:)]' '/ProcID./{ count++; if(count == 2 ){ printf "mv %s %s.txt\n", FILENAME, $2 | "/bin/sh"; nextfile}}' O*.TXT
    – user633715
    Jan 30, 2017 at 8:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .