find list of files not modified for last 30 days in clearcase - find

I need to find list of files which are not modified for last 30 days. This means there should be no version of the file under any branch in last 30 days. is this possible in base clearcase?

Try first, from the query_language and cleartool find, the syntax
cleartool find <vobtag> -element "!{created_since(target-data-time)}" -print
If that does not work, you would then have to fallback to:
list all files with a version created in the last 30 days
list all files and extract the ones which are not part of the first list.
Regarding said first list (from "How to determine the last time a VOB was modified"), using cleartool find:
cleartool find <vobtag> -element "{created_since(target-data-time)}" -print
or
cleartool find <vobtag> -version "{created_since(target-data-time)}" -print
That document also mentions cleartool lshistory -minor -all ., but that unreliable as it uses local metadata that can be scrapped at any time.
For the second list:
cleartool find . -cview -ele -print

Here is a sample Perl script to do what you're asking for. This has a hard-coded date string to avoid getting bogged down in Perl date arithmetic. It takes the list of all elements in the VOB, and then deletes elements with versions modified since the date specified from that list, finally outputting the non-modified elements.
#!/usr/bin/Perl -w
my %elem_hash;
my $datestring="01-jan-2014";
my $demarq= "-------------------------------------------------";
my $allelemtxt="-- All elements located in the current VOB --";
my $ver_hdr ="-- Versions modified since $datestring --";
my $nonmodtext="-- Elements not modified since $datestring --";
#
# Get all elements in the current VOB.
#
$cmdout=`cleartool find -all -print`;
#elemtext=split('\n',$cmdout);
#
# Add them to a hashmap, simply because it's easier to delete from this list type
#
foreach $elem (#elemtext)
{
# Quick and dirty way to remove the ##
$elem = substr($elem,0,length($elem)-2);
$elem_hash{$elem} = 1;
}
#
printf("\n%s\n%s\n%s\n",$demarq,$allelemtxt,$demarq);
foreach $elem2 (sort (keys (%elem_hash)))
{
printf("Element: %s\n",$elem2);
}
#
# Get VERSIONS modified since the specified date string
#
$cmdout=`cleartool find -all -version "created_since($datestring)" -print`;
#vertext=split('\n',$cmdout);
#
# strip the trailing version id's and then delete the resulting key from the hashmap.
#
printf("\n%s\n%s\n%s\n",$demarq,$ver_hdr,$demarq);
foreach $version (#vertext)
{
printf("Version: %s\n",$version);
$version=substr($version,0,length($version)-(length($version)- rindex($version,"##")));
if (exists($elem_hash{$version}))
{
delete $elem_hash{$version};
}
}
printf("\n%s\n%s\n%s\n",$demarq,$nonmodtext,$demarq);
foreach $elem2 (sort (keys (%elem_hash)))
{
printf("Element: %s\n",$elem2);
}

Related

Search for a match, after the match is found take the number after the match and add 4 to it, it is posible in perl?

I am a beginer in perl and I need to modify a txt file by keeping all the previous data in it and only modify the file by adding 4 to every number related to a specific tag (< COMPRESSED-SIZE >). The file have many lines and tags and looks like below, I need to find all the < COMPRESSED-SIZE > tags and add 4 to the number specified near the tag:
< SOURCE-START-ADDRESS >01< /SOURCE-START-ADDRESS >
< COMPRESSED-SIZE >132219< /COMPRESSED-SIZE >
< UNCOMPRESSED-SIZE >229376< /UNCOMPRESSED-SIZE >
So I guess I need to do something like: search for the keyword(match) and store the number 132219 in a variable and add the second number (4) to it, replace the result 132219 with 132223, the rest of the file must remain unchanged, only the numbers related to this tag must change. I cannot search for the number instead of the tag because the number could change while the tag will remain always the same. I also need to find all the tags with this name and replace the numbers near them by adding 4 to them. I already have the code for finding something after a keyword, because I needed to search also for another tag, but this script does something else, adds a number in front of a keyword. I think I could use this code for what i need, but I do not know how to make the calculation and keep the rest of the file intact or if it is posible in perl.
while (my $row = <$inputFileHandler>)
{
if(index($row,$Data_Pattern) != -1){
my $extract = substr($row, index($row,$Data_Pattern) + length($Data_Pattern), length($row));
my $counter_insert = sprintf "%08d", $counter;
my $spaces = " " x index($row,$Data_Pattern);
$data_to_send ="what i need to add" . $extract;
print {$outs} $spaces . $Data_Pattern . $data_to_send;
$counter = $counter + 1;
}
else
{
print {$outs} $row;
next;
}
}
Maybe you could help me with a block of code for my needs, $Data_Pattern is the match. Thank you very much!
This is a classic one-liner Perl task. Basically you would do something like
$ perl -i.bak -pe's/^< COMPRESSED-SIZE >\K(\d+)/$1 + 4/e' yourfile.txt
Which will in essence copy and replace your file with a new, edited file. This can be very dangerous, especially if you are a Perl newbie. The -i switch is here used with the .bak extension which saves a backup in yourfile.txt.bak. This does not make this operation safe, however, as running the command twice will overwrite the backup.
It is advisable to make a separate backup of the target file before using this command.
-i.bak edit "in-place", the file is overwritten, a backup of the original is created with extension .bak.
-p argument is treated as a file name, which is read, and printed back.
s/ // the substitution operator, which is applied to all lines of the file.
^ inside the regex looks for beginning of line.
\K keep the match that is to the left.
(\d+) capture () 1 or more digits \d+ and store them in $1
/e treat the right hand side of the substitution operator as an expression and use the result as the replacement string. In this case it will increase your number and return the sum.
The long version of this command is
while (<>) {
s/^< COMPRESSED-SIZE >\K(\d+)/$1 + 4/e
}
Which can be placed in a file and run with the -i switch.

How to exclude some files using file::find::rule module using perl?

I had tried to remove the files which ever named along with digits but it is not happening in my code.Here $output is my directory location.In which the directory contains multiple folders and sub folders.
From that folders and sub folders i want to pick my .ml files .In which the only the aplhabets named .ml files to be listed.
If the file names comes like(ev4.html,ev8.html and so on it should be omitted).
Because here the file names comes along with the digits so i want to exclude the files which ever named along with digits and print the excepted output.
Here is my code:
use strict;
use warnings;
use File::Find::Rule;
my $output="/home/location/radio/datas";
my #files=File::Find::Rule->file()
->name('*.ml')
#->name(qr/\^ev\d+/)->prune->discard
->in($output);
for my $file(#files)
{
print "file:$file\n";
}
Obtained output:
file:/dacr/dacr.ml
file:/DV/DV.ml
file:DV/ev4/ev4.ml
Expected Output:
file:/dacr/dacr.ml
file:/DV/DV.ml
Your attempt was almost correct, but your regular expression is wrong, and the prune and discard will remove all files, not only the ones for the regex.
my #files=File::Find::Rule->file()
->name('*.ml')
->name(qr/\^ev\d+/) # wrong regex
->prune->discard # throws away all files
->in($output);
The correct regular expression to get files that contain any digit is simply \d. You are saying a literal ^, the letters ev and any number of digits, at least one.
To make File::Find::Rule take all files that end in .ml and then not the ones that have a digit, use not.
my #files=File::Find::Rule->file()
->name('*.ml')
->not( File::Find::Rule->name(qr/\d/) )
->in($output);
This will get all .ml files, and discard any file that has any digit in the name.

perl quoting in ftp->ls with wildcard

contents of remote directory mydir :
blah.myname.1.txt
blah.myname.somethingelse.txt
blah.myname.randomcharacters.txt
blah.notmyname.1.txt
blah.notmyname.2.txt
...
in perl, I want to download all of this stuff with myname
I am failing really hard with the appropriate quoting. please help.
failed code
my #files;
#files = $ftp->ls( '*.myname.*.txt' ); # finds nothing
#files = $ftp->ls( '.*.myname.*.txt' ); # finds nothing
etc..
How do I put the wildcards so that they are interpreted by the ls, but not by perl? What is going wrong here?
I will assume that you are using the Net::FTP package. Then this part of the docs is interesting:
ls ( [ DIR ] )
Get a directory listing of DIR, or the current directory.
In an array context, returns a list of lines returned from the server. In a scalar context, returns a reference to a list.
This means that if you call this method with no arguments, you get a list of all files from the current directory, else from the directory specified.
There is no word about any patterns, which is not suprising: FTP is just a protocol to transfer files, and this module only a wrapper around that protocoll.
You can do the filtering easily with grep:
my #interesting = grep /pattern/, $ftp->ls();
To select all files that contain the character sequence myname, use grep /myname/, LIST.
To select all files that contain the character sequence .myname., use grep /\.myname\./, LIST.
To select all files that end with the character sequence .txt, use grep /\.txt$/, LIST.
The LIST is either the $ftp->ls or another grep, so you can easily chain multiple filtering steps.
Of course, Perl Regexes are more powerful than that, and we could do all the filtering in a single /\.myname\.[^.]+\.txt$/ or something, depending on your exact requirements. If you are desperate for a globbing syntax, there are tools available to convert glob patterns to regex objects, like Text::Glob, or even to do direct glob matching:
use Text::Glob qw(match_glob);
my #interesting = match_glob ".*.myname.*.txt", $ftp->ls;
However, that is inelegant, to say the least, as regexes are far more powerful and absolutely worth learning.

How can I interact with ClearCase from Perl?

My project needs couple of things to be extracted from ClearCase data using the Perl script in a excel sheet,those are -
By giving two particular time line or two baseline.
all the activity associated within that baseline (column header "activity")
Owner's id (column header-Owner)
all the element associated within a particular activity. (column header-"element details")
For each element the versions associated (column header-"Versions")
for each element the total number of lines of code,total number of lines of code added,total number of lines of code deleted,total number of lines of code changed..(column header"No. of lines of code","lines of code added","lines of code deleted" & " lines of code changed")
Please kindly help me on this...
Basically, ClearCase Perl scripting is based on parsed outputs of system and cleartool commands.
The scripts are based on a cleartool run cmd like package CCCmd, and used like:
use strict;
use Config;
require "path/to/CCCmd.pm";
sub Main
{
my $hostname = CCCmd::RunCmd('hostname');
chomp $hostname;
my $lsview = CCCmd::ClearToolNoError("lsview -l -pro -host $hostname");
return 1;
}
Main() || exit(1);
exit(0);
for instance.
So once you have the basic Perl structure, all you need is the right cleartool commands to analyze, based on fmt_ccase directives.
1/ all the activity associated within that baseline (column header "activity")
ct descr -fmt "%[activities]CXp" baseline:aBaseline.xyz#\ideapvob
That will give you the list of activities (separated by ',').
For each activity:
2/ Owner's id (column header-Owner)
ct descr -fmt "%u" activity:anActivityName#\ideapvob
3/ all the element associated within a particular activity. (column header-"element details")
Not sure: activities can list their versions (see /4), not easily their elements
4/ For each element the versions associated (column header-"Versions")
For a given activity:
ct descr -fmt "%[versions]CQp\n" activity:anActivityName#\ideapvob
5/ for each element the total number of lines of code,total number of lines of code added,total number of lines of code deleted,total number of lines of code changed..(column header"No. of lines of code","lines of code added","lines of code deleted" & " lines of code changed")
That can be fairly long, but for each version, you can compute the extended path of the previous version and make a diff.
I would advise using for all that a dynamic view, since you can access any version of a file from there (as opposed to a snapshot view).
Also if you need to use perl with Clearcase have a look at the CPAN module ClearCase::CtCmd. I would recommend to use this perl module for invoking clearcase commands.
For the CCCmd package, I had to remove the double-quotes in the RunCmd and RunCmdNoError subs to get it to work.

ClearCase: How to find elements that do NOT have a particular label

I'm looking for a ClearCase command that will list all the elements that are visible in my current view, but do NOT have a particular label applied to them.
Say for example, most of the elements that are visible in my view have LABEL_X applied to them. I want a list of those elements that do not have LABEL_X.
I obviously need to use cleartool find, but the usage and ClearCase man page baffle me in terms of how to construct a query like this.
This should work:
ct find -all -ele '! lbtype_sub(LABEL_X)' -print
ct find -ele '! lbtype_sub(LABEL_X)' -print
Notes:
ct stands for cleartool
Unix syntax here (for windows, replace simple quotes with double quotes)
beware of the space between ! and lbtype_sub (in winodws you do not need the space)
-ele very IMPORTANT to get only one occurrence of a given file (and not all the different versions of a file matching a criteria)
-ele limits the search to elements, not versions (that would trigger a lot more results with versions involved...)
-all list all elements included "deleted" (that is "unreferenced") ones.
The second line lists only visible elements (in the current view)
You should execute those second command lines on the sub-directory of your choice within a given ClearCase (snapshot or dynamic view): all files within that sub-directory (and sub-sub directories...) matching the cirteria will be listed.
Warnings:
files and directories are listed. If you want only files, add -type f to the query:
ct find -type f -ele '!lbtype_sub(LABEL_X)' -print
what is displayed is the extended path for elements, that is the name of the file followed with ##.
To list only the name without ##, use '-nxn' (no extendedpathname option)
ct find -nxn -ele '!lbtype_sub(LABEL_X)' -print
Another more complex but also more complete way to list only the name without ##, is to use descr -fmt. For instance:
ct find . -ele "!lbtype_sub(LABEL_X)" -exec "cleartool descr -fmt \"%En %d\n\" \"%CLEARCASE_PN%\""
ct find . -ele '! lbtype_sub(LABEL_X)' -exec 'cleartool descr -fmt "%En %d\n" "$CLEARCASE_PN"'
would give you (in windows or unix syntax) the date and name of the files and directories not labeled LABEL_X.
With that 'descr -fmt' display, you can combine any kind of information and presentation you want for the result.
Above works, but remember to specifiy -cview to get JUST the current view, otherwise you'll get files from all the other views as well.
I needed to use the following on my Linux clearcase install:
cleartool find -cview -all -version '\!lbtype(LABEL_X)' -print
The syntax from VonC's post did not work properly with the "!" not being escaped.