Move Values In Perl Array - perl
I am having difficulty placing array columns in a format that is consistent. I have the following output:
Mon,Jun,25,14:39:29,2012,971,29,0,25,0,0,0,4,Mon,Jun,25,14:39:29,2012,25,mod_was_ap22_http.c
Mon,Jun,25,14:40:29,2012,972,28,0,25,0,0,0,3,Mon,Jun,25,14:40:29,2012,3,mod_sm22.cpp,22,mod_was_ap22_http.c
Mon,Jun,25,14:41:29,2012,973,27,0,24,0,0,0,3,Mon,Jun,25,14:41:29,2012,24,mod_was_ap22_http.c
Mon,Jun,25,14:42:29,2012,974,26,0,20,0,0,0,6,Mon,Jun,25,14:42:29,2012,1,mod_sm22.cpp,19,mod_was_ap22_http.c
Mon,Jun,25,14:43:29,2012,971,29,0,26,0,0,0,3,Mon,Jun,25,14:43:29,2012,2,mod_sm22.cpp,24,mod_was_ap22_http.c
Mon,Jun,25,14:44:30,2012,957,43,0,41,0,0,0,2,Mon,Jun,25,14:44:30,2012,1,mod_sm22.cpp,40,mod_was_ap22_http.c
Mon,Jun,25,14:45:30,2012,963,37,0,35,0,0,0,2,Mon,Jun,25,14:45:30,2012,2,mod_sm22.cpp,32,mod_was_ap22_http.c
Mon,Jun,25,14:46:30,2012,972,28,0,24,1,1,0,2,Mon,Jun,25,14:46:30,2012,24,mod_was_ap22_http.c,1,ApacheModule.cpp
Mon,Jun,25,14:47:30,2012,961,39,1,37,0,0,0,1,Mon,Jun,25,14:47:30,2012,37,mod_was_ap22_http.c,1,ApacheModule.cpp
Mon,Jun,25,14:48:30,2012,968,32,0,30,0,0,0,2,Mon,Jun,25,14:48:30,2012,30,mod_was_ap22_http.c
Mon,Jun,25,14:49:30,2012,972,28,0,25,0,0,0,3,Mon,Jun,25,14:49:30,2012,1,mod_sm22.cpp,24,mod_was_ap22_http.c
I would like the columns to display:
DayOfWeek,Month,Day,Time,Year,Rdy,Bsy,Rd,Wr,Ka,Log,Dns,Cls,AP22,SM22,ApacheModule
Currently the columns in bold are not in that order (the rest are correct). Each line isn't consistent with that format. The line sometimes has ap22 first, sometimes has sm22 first, and sometimes has none or all three modules. The number before the module relates to the module. How can I move the data into a consistent format?
Note that the 2nd date, mod_was_http.c, mod_sm22.cpp, and ApacheModule.cpp in each line will be removed in the final array.
Here is my code so far:
# This program parses a error log for necessary information and outputs in CSV format.
# chunks of your input to ignore, see below...
my %ignorables = map { $_ => 1 } qw([notice mpmstats: rdy bsy rd wr ka log dns cls bsy: in);
# 3-arg open is safer than 2, lexical my $fh better than a global FH glob
open my $error_fh, '<', 'iset_error_log';
sub findLines {
my($item,#result)=("");
# Iterates over the lines in the file, putting each into $_
while (<$error_fh>) {
# Select only those fields that have the word 'notice'
if (/\[notice/) {
# Place those lines with the word 'rdy' on the next line
if (/\brdy\b/){
push #result,"$item\n";
$item="";
}
else {
$item.=",";
}
# Split the line into fields, separated by spaces, skip the %ignorables
my #line = grep { not defined $ignorables{$_} } split /\s+/;
# More cleanup
s/|^\[|notice|[]]//g for #line; # remove unnecessary elements from the array
# Output the line.
#line = join(",", #line);
s/,,/,/g for #line;
map $item.=$_, #line;
}
}
#result
}
my #array = &findLines;
foreach $line (#array){
print $line; #This is where I would like to organize the lines if possible.
}
My input file looks like this:
[Mon Jun 25 07:51:17 2012] [notice] mpmstats: rdy 990 bsy 10 rd 0 wr 7 ka 0 log 0 dns 0 cls 3
[Mon Jun 25 07:51:17 2012] [notice] mpmstats: bsy: 2 in mod_sm22.cpp, 5 in mod_was_ap22_http.c
[Mon Jun 25 08:08:17 2012] [notice] mpmstats: rdy 974 bsy 26 rd 1 wr 24 ka 0 log 0 dns 0 cls 1
[Mon Jun 25 08:08:17 2012] [notice] mpmstats: bsy: 1 in mod_sm22.cpp, 23 in mod_was_ap22_http.c, 1 in ApacheModule.cpp Mon,Jun,25,14:38:29,2012,962,38,0,36,0,0,0,2,Mon,Jun,25,14:38:29,2012,3,mod_sm22.cpp,33,mod_was_ap22_http.c
[Mon Jun 25 21:54:41 2012] [notice] mpmstats: rdy 999 bsy 1 rd 0 wr 0 ka 0 log 0 dns 0 cls 1
[Mon Jun 25 21:55:41 2012] [notice] mpmstats: rdy 999 bsy 1 rd 0 wr 0 ka 0 log 0 dns 0 cls 1
[Mon Jun 25 21:59:41 2012] [notice] mpmstats: rdy 999 bsy 1 rd 0 wr 1 ka 0 log 0 dns 0 cls 0
[Mon Jun 25 21:59:41 2012] [notice] mpmstats: bsy: 1 in mod_was_ap22_http.c
[Mon Jun 25 22:00:41 2012] [notice] mpmstats: rdy 999 bsy 1 rd 0 wr 1 ka 0 log 0 dns 0 cls 0
[Mon Jun 25 22:00:41 2012] [notice] mpmstats: bsy: 1 in mod_was_ap22_http.c
[Mon Jun 25 22:03:41 2012] [notice] mpmstats: rdy 998 bsy 2 rd 0 wr 2 ka 0 log 0 dns 0 cls 0
[Mon Jun 25 22:03:41 2012] [notice] mpmstats: bsy: 2 in mod_was_ap22_http.c
[Mon Jun 25 22:08:42 2012] [notice] mpmstats: rdy 998 bsy 2 rd 0 wr 2 ka 0 log 0 dns 0 cls 0
[Mon Jun 25 22:08:42 2012] [notice] mpmstats: bsy: 2 in mod_was_ap22_http.c
[Mon Jun 25 22:21:42 2012] [notice] mpmstats: rdy 999 bsy 1 rd 0 wr 1 ka 0 log 0 dns 0 cls 0
[Mon Jun 25 22:21:42 2012] [notice] mpmstats: bsy: 1 in mod_was_ap22_http.c
[Mon Jun 25 22:22:42 2012] [notice] mpmstats: rdy 999 bsy 1 rd 0 wr 1 ka 0 log 0 dns 0 cls 0
[Mon Jun 25 22:22:42 2012] [notice] mpmstats: bsy: 1 in mod_was_ap22_http.c
[Mon Jun 25 22:31:42 2012] [notice] mpmstats: rdy 999 bsy 1 rd 0 wr 0 ka 0 log 0 dns 0 cls 1
[Mon Jun 25 22:32:42 2012] [notice] mpmstats: rdy 999 bsy 1 rd 0 wr 1 ka 0 log 0 dns 0 cls 0
[Mon Jun 25 22:32:42 2012] [notice] mpmstats: bsy: 1 in mod_was_ap22_http.c
[Mon Jun 25 23:06:43 2012] [notice] mpmstats: rdy 999 bsy 1 rd 0 wr 1 ka 0 log 0 dns 0 cls 0
[Mon Jun 25 23:06:43 2012] [notice] mpmstats: bsy: 1 in mod_was_ap22_http.c
You probably want to reorder the columns while you still have the split, before you use join to turn them back into a line of text.
You just need to do a swap.
# 0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ,11 ,12 ,13 ,14 ,15
# DayOfWeek,Month,Day,Time,Year,Rdy,Bsy,Rd,Wr,Ka,Log,Dns,Cls,AP22,SM22,ApacheModule
#
# Sometimes the last 2 fields are missing and 13 comes before 14 and 15 in the
# input, so fix that.
if (#line < 16) {
push #line, '', ''; # or whatever you want for blanks
}
#line = #line[0..12,14,15,13]; # rearrange the array
Also, your regular expression s/,,/,/g is going to break this if you use blank strings ('') as your empty fields. The short lines missing the last fields will go back to being short missing the correct 13 and 14 fields.
Based upon the kinds of questions being asked here and previously, I highly recommend you get a copy of Modern Perl (available for download or purchase) or Learning Perl to get a better grasp of the language as a whole. I have recently read much of the former and enjoyed it and gained most of my initial Perl knowledge from an earlier edition of the latter.
Related
Prevent OOM inside container
I'm running conda install -c anaconda pycodestyle in a container with this spec: apiVersion: v1 kind: Pod metadata: name: conda-${PYTHON_VERSION} spec: securityContext: runAsUser: 0 runAsGroup: 0 containers: - name: python image: continuumio/conda-ci-linux-64-python${PYTHON_VERSION} command: - /bin/bash args: - "-c" - "sleep 99d" workingDir: /home/jenkins/agent resources: requests: memory: "256Mi" cpu: "1" limits: memory: "256Mi" cpu: "1" My understanding was that if I set limits and requests to the same value, OOM won't be called... seems like I was wrong. To make myself clear: I don't want overprovisioning to happen at all, I don't want the kernel to panic, if it allocated memory it cannot back up with real memory. Ideally, I want to understand how to prevent these errors from happening in Kubernetes at all, not specifically for conda, but if there's any way to limit conda to a particular amount of memory, it'll help too. The machine running these containers has 16MB of memory, and it might, at most, try to run three of those. The OMM message looks like this: 14:07:03 2021] Task in /kubepods/burstable/poda6df66b5-bfc5-43be-b02d-66f09e7ecf0f/2203670eb25d83d72428831a35773b90445f19ee37c117f196d6774442022db8 killed as a result of limit of /kubepods/burstable/poda6df66b5-bfc5-43be-b02d-66f09e7ecf0f/2203670eb25d83d72428831a35773b90445f19ee37c117f196d6774442022db8 [Wed Jul 21 14:07:03 2021] memory: usage 262144kB, limit 262144kB, failcnt 17168 [Wed Jul 21 14:07:03 2021] memory+swap: usage 0kB, limit 9007199254740988kB, failcnt 0 [Wed Jul 21 14:07:03 2021] kmem: usage 11128kB, limit 9007199254740988kB, failcnt 0 [Wed Jul 21 14:07:03 2021] Memory cgroup stats for /kubepods/burstable/poda6df66b5-bfc5-43be-b02d-66f09e7ecf0f/2203670eb25d83d72428831a35773b90445f19ee37c117f196d6774442022db8: cache:104KB rss:250524KB rss_huge:0KB shmem:0KB mapped_file:660KB dirty:0KB writeback:0KB inactive_anon:125500KB active_anon:125496KB inactive_file:8KB active_file:12KB unevictable:0KB [Wed Jul 21 14:07:03 2021] Tasks state (memory values in pages): [Wed Jul 21 14:07:03 2021] [ pid ] uid tgid total_vm rss pgtables_bytes swapents oom_score_adj name [Wed Jul 21 14:07:03 2021] [3659435] 0 3659435 1012 169 40960 22 984 sleep [Wed Jul 21 14:07:03 2021] [3660809] 0 3660809 597 155 45056 26 984 sh [Wed Jul 21 14:07:03 2021] [3660823] 0 3660823 597 170 40960 18 984 sh [Wed Jul 21 14:07:03 2021] [3660824] 0 3660824 597 14 40960 9 984 sh [Wed Jul 21 14:07:03 2021] [3660825] 0 3660825 597 170 45056 23 984 sh [Wed Jul 21 14:07:03 2021] [3660827] 0 3660827 162644 44560 753664 38159 984 conda [Wed Jul 21 14:07:03 2021] [3660890] 0 3660890 1012 169 49152 22 984 sleep [Wed Jul 21 14:07:03 2021] Memory cgroup out of memory: Kill process 3660827 (conda) score 1123 or sacrifice child [Wed Jul 21 14:07:03 2021] Killed process 3660827 (conda) total-vm:650576kB, anon-rss:165968kB, file-rss:12272kB, shmem-rss:0kB [Wed Jul 21 14:07:03 2021] oom_reaper: reaped process 3660827 (conda), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB I also don't like the word "burstable" here... I thought it was supposed to be "guaranteed"
Picking up files from a directory in perl
I have gone through a bunch of questions to find the best way to get the names of the files from a directory. However, I have a peculiar scenario and need some help. The files in my direcotry are as follows -rw-rw-r-- 1 root 55000 53916 Apr 12 2013 Update_2013-04-12_02-17-55.txt -rw-rw-r-- 1 root 55000 53916 Apr 12 2013 UpdateCIMS_2013-04-12_03-20-30.txt -rw-rw-r-- 1 root 55000 53763 Apr 15 2013 UpdateCIMSFlag_2013-04-15_05-47-41.txt -rw-rw-r-- 1 root 55000 91981 Apr 23 2013 UserManagementService_2013-04-23_03-55-52.txt -rw-rw-r-- 1 root 55000 92076 Apr 23 2013 UserManagementService_2013-04-23_04-34-42.txt -rw-rw-r-- 1 root 55000 92086 Apr 23 2013 UserManagementService_2013-04-23_23-55-10.txt -rw-rw-r-- 1 root 55000 91971 Apr 24 2013 UserManagementService_2013-04-24_02-23-20.txt -rw-rw-r-- 1 root 55000 59441 Apr 24 2013 SecuredService_2013-04-24_02-29-08.txt -rw-rw-r-- 1 root 55000 42240 May 20 2013 UpdateCIMSFlag_2013-05-20_04-24-19.txt -rw-rw-r-- 1 root 55000 40547 May 20 2013 UpdateCIMSFlag_2013-05-20_05-31-29.txt -rw-rw-r-- 1 root 55000 42238 May 20 2013 UpdateCIMSFlag_2013-05-20_05-43-54.txt -rw-rw-r-- 1 root 55000 59493 May 21 2013 SecuredService_2013-05-21_04-25-32.txt -rw-rw-r-- 1 root 55000 88374 May 21 2013 RegistrationService_2013-05-21_23-55-33.txt -rw-rw-r-- 1 root 55000 88426 May 22 2013 RegistrationService_2013-05-22_00-20-04.txt -rw-rw-r-- 1 root 55000 60014 Jul 31 04:16 SecuredService_2013-07-31_04-16-56.txt -rw-rw-r-- 1 root 55000 91636 Sep 2 06:11 AdminServices_2013-09-02_06-11-17.txt -rw-rw-r-- 1 root 55000 91649 Sep 3 05:37 AdminServices_2013-09-03_05-37-54.txt -rw-rw-r-- 1 root 55000 133629 Sep 3 05:43 UserManagementService2_2013-09-03_05-43-56.txt -rw-rw-r-- 1 root 55000 556 Sep 9 08:26 Test_2013-09-09_08-26-23.txt -rw-rw-r-- 1 root 55000 556 Sep 9 08:37 Test_2013-09-09_08-37-20.txt -rw-rw-r-- 1 root 55000 133708 Sep 13 02:28 UserManagementService2_2013-09-13_02-28-49.txt -rw-rw-r-- 1 root 55000 60107 Sep 13 02:30 SecuredService_2013-09-13_02-30-43.txt -rw-rw-r-- 1 root 55000 133743 Sep 13 04:44 UserManagementService2_2013-09-13_04-44-29.txt -rw-rw-r-- 1 root 55000 100886 Sep 16 04:27 AdminServices_2013-09-16_04-27-33.txt -rw-rw-r-- 1 root 55000 556 Sep 20 06:40 Test_2013-09-20_06-40-16.txt -rw-rw-r-- 1 root 55000 110236 Nov 25 02:35 AdminServices_2013-11-25_02-35-37.txt -rw-rw-r-- 1 root 55000 142357 Dec 18 03:13 UserManagementService2_2013-12-18_03-13-20.txt As you can see, i have similar files with different timestamps and different files. So i need the file names which are similar excluding the timestamp and the latest file from them. I want my end result to display the latest, unique filenames with the timestamp. I am trying opendir but am not seeing any result. #!/usr/bin/perl use File::stat; my $DIR = "/home/DIR"; opendir(my $DH, $DIR) or die "Error opening the dir"; my %files = map { $_ => (stat("$DIR/$_"))[9] } grep(! /^\.\.?$/, readdir($DH)); closedir($DH); my #sorted_files = sort { $files{$b} <=> $files{$a} } (keys %files); print $_; Please help. The output I am expecting is AdminServices_2013-11-25_02-35-37.txt UserManagementService2_2013-12-18_03-13-20.txt SecuredService_2013-09-13_02-30-43.txt RegistrationService_2013-05-22_00-20-04.txt etc...
For a start, opendir isn't the problem. You aren't using the print statement correctly. foreach(#sorted_files) { print $_ . "\n"; } That outputs the file names. This is only a start to get you some output. I didn't finish the problem.
#!/usr/bin/perl my $DIR = "/home/DIR"; opendir(my $DH, $DIR) or die $!; my %files; while (my $f = readdir($DH)) { next if $f =~ /^\.\.?$/; my ($key, $t) = split /_/, $f, 2; # #{ $files{$key} }{ "t","f" } = ($t, $f) # if !$files{$key} or $files{$key}{t} lt $t; my $h = $files{$key} ||= {}; if (! %$h or $h->{t} lt $t) { $h->{t} = $t; $h->{f} = $f; } } print "$files{$_}{f}\n" for sort keys %files;
You could use glob: my $filespec = "/tmp/test*"; my %files; while (my $file = glob("$filespec") ){ next if $file eq '.' or $file eq '..'; next if ! -f $file; my $datestamp = (stat($file))[9]; #remove timestamp my $filename = $file; $filename =~ s!_\d{4}-\d{2}-\d{2}_\d{4}-\d{4}-\d{4}\.\W{3}\z!!is; if (! exists $files{$filename} || $files{$filename}<$datestamp){ $files{$filename} = $datestamp; $files{$filename} = $datestamp; } } foreach my $key (sort { $files{$b} <=> $files{$a} } (keys %files)){ print "$key\t$files{$key}\n"; }
Print command result side by side?
It is possible to print the result of 2 commands side by side... Something like this something `ls -l /a` `cat bla.txt` result: total 24 #while [ 1 = 1 ]; do -rw-r--r-- 1 wolfy wolfy 194 Aug 13 08:50 c.in # echo "bla" -rwxr-xr-x 1 wolfy wolfy 52 Sep 24 11:48 bla.sh #done -rwxr-xr-x 1 wolfy wolfy 38 Sep 24 11:48 bla1.sh echo "bla" -rwxr-xr-x 1 wolfy wolfy 147 Sep 24 11:54 ble.sh I know that pr can do something like this with files, but I didn't find a way to do this for commands...
You can use process substitution pr -m <(cmd1) <(cmd2) though in your case, since you have one command and one file: ls -l | pr -m - bla.txt
copy specific file in command line
I want to copy specific file done last changes in Oct 16-17,file type is java. shia#ubuntu:~/code$ ls -alxo total 96 drwx------ 2 shia 4096 Oct 20 18:54 . drwxr-xr-x 61 shia 12288 Oct 20 19:24 .. -rw------- 1 shia 12288 Oct 16 21:52 .Reuse.java.swp -rw-rw-r-- 1 shia 746 Oct 20 11:16 Argus.class -rw-rw-r-- 1 shia 302 Oct 20 11:16 Argus.java -rw------- 1 shia 310 Oct 16 21:30 Call.java -rw-rw-r-- 1 shia 417 Oct 17 15:20 Ordinary.class -rw-rw-r-- 1 shia 298 Oct 17 14:57 Overriding.java -rw-rw-r-- 1 shia 562 Oct 19 21:27 Package.class -rw-rw-r-- 1 shia 430 Oct 19 21:27 Package.java -rw------- 1 shia 729 Oct 17 13:50 Reuse.java -rw------- 1 shia 424 Oct 17 13:47 Room.java -rw------- 1 shia 321 Oct 16 21:22 Simpleobject.java -rw-rw-r-- 1 shia 1187 Oct 17 00:04 Static.java -rw-rw-r-- 1 shia 686 Oct 17 15:20 Super.class -rw-rw-r-- 1 shia 1010 Oct 17 15:20 Super.java -rw------- 1 shia 843 Oct 17 14:20 This.java -rw-rw-r-- 1 shia 521 Oct 17 14:51 b.java -rw-rw-r-- 1 shia 90 Oct 20 18:54 cp.awk -rw-rw-r-- 1 shia 105 Oct 20 17:19 file.txt I try to specific them but i don't know how to copy them. shia#ubuntu:~/code$ ls -alxo|grep 'Oct 1[67].*java$'|awk '{print $8}' Call.java Overriding.java Reuse.java Room.java Simpleobject.java Static.java Super.java This.java b.java Any help,thanks a lot!
One way using find: find . -maxdepth 1 -type f -name "*.java" -newermt 2012-10-16 ! -newermt 2012-10-18 -exec cp '{}' /home/user/dstFolder/ \;
You can use xargs to copy the files found: ...| xargs -i cp '{}' /home/user/dstFolder/ This will copy all the files found to the folder /home/user/dstFolder/.
sphinx inconsistent result
have some weird problems with sphinx. Here's the query log: [Mon Jan 31 05:43:21.362 2011] 0.158 sec [any/0/ext 511 (0,2000)] [_file] superman [Mon Jan 31 05:43:51.739 2011] 0.143 sec [any/0/ext 952 (0,2000)] [_file] superman [Mon Jan 31 05:44:22.042 2011] 0.003 sec [any/0/ext 952 (0,2000)] [_file] superman [Mon Jan 31 05:44:52.313 2011] 0.003 sec [any/0/ext 952 (0,2000)] [_file] superman [Mon Jan 31 05:45:22.553 2011] 0.003 sec [any/0/ext 952 (0,2000)] [_file] superman If you see, the result returned is 511 for the first time, then 952 (the correct result) for the rest. I've tried searching with different result and all seems to be the same. Some observation: 1) If there's less than 511, the result returned is always correct. It's only when the result is > 511 and less than the max that it is wrong. 2) If there are more result than the max, the returned result will be max (correct). 3) The rest of the results are usually correct, up until the sphinx db re-indexed. Then we'll get 511 again. Tried it on different sphinx installation, getting the same result. my client code: $cl->setServer("localhost", 3312); $cl->setMaxQueryTime(10); $cl->SetLimits(0, 2000, 2000); $cl->setMatchMode(SPH_MATCH_ANY); call_user_func_array(array($cl, 'setSortMode'), array(SPH_SORT_EXTENDED, '#id DESC')); $result = $cl->query('superman', '_file'); sphinx.conf: index download_file { source = file path = /disk1/data/sphinx/file morphology = stem_en enable_star=1 min_word_len = 3 min_prefix_len = 0 min_infix_len = 3 } searchd { max_matches = 100000 port = 3312 log = /var/log/searchd/searchd.log query_log = /var/log/searchd/query.log pid_file = /var/log/searchd/searchd.pid } indexer { max_iops = 40 mem_limit = 128M }