I have a hash. The value for the key in hash is concatenation of 2 strings. ($value1 and $value2)
When I print the value of concatenated variable $values it prints with the newline.
But when I am printing it in html table format the newline doesn't exist. How can I have the newline retained.
my $value1 = "Good files are 272 :10%";
my $value2 = "Bad files are 300 : 15%";
my $values = $value1 . $value2;
print "values : $values ";
# HASH with multiple values for each key
my %hash ;
$keyvalue = "foobar";
$hash{$keyvalue} = $values ;
# SET UP THE TABLE
print "<table border='1'>";
print "<th>Category</th><th>value</th>";
#Print key and values in hash in tabular format
foreach $key (sort keys %hash) {
print "<tr><td>".$key."</td>";
print "<td>".$hash{$key}."</td>";
}
* Current Output: *
It prints the hash values without newline
values : Good files are 272 :10%
Bad files are 300 : 15%
Category Value
foobar Good files are 272 :10%Bad files are 300 : 15%
* Desired Output: *
Category Value
foobar Good files are 272 :10%
Bad files are 300 : 15%
In HTML, you use the <br> element to create a new line. Therefore, just do a search and replace -- replace any line breaks in your input with <br>.
Since you're concatenating $value1 and $value2, you can do this:
$values = $value1 . '<br>' . $value2;
Related
I stored the output of uniq -c into two files $lfile and $lfile2, I tried to make column separator as " " with tr command, but it seems not working, after split of $line there nothing get stored in $count, $e_code.
How to split the $line in two parts?
`egrep -o [A-Z]{3}[0-9]{5} $e_file |sort|uniq -c |sort -nrk1 |head -15 >$lfile1`;
`egrep -o [A-Z]{3}[0-9]{5} $y_file |sort|uniq -c |sort -nrk1 |head -150 >$lfile2`;
open (IN, "<$lfile1") ;
foreach $line (<IN>)
{
my $f_line=`echo $line|tr -s ' ' ` ;
print "$f_line \n" ;
my ($count, $e_code) = split / /, $f_line;
uniq -c produces output similar to this:
2 ABC12345
1 ZXC09876
Notice the leading spaces. Apparently, you intended to strip the leading spaces but keeping the space in between is vital for split / /, $f_line; to succeed.
To remove the leading spaces only use ^\s+ pattern (^ is the start of line anchor) and pass it to s/// substitution operator:
$line =~ s/^\s+//;
Please note you may accomplish this task in pure Perl:
my %counts = ();
open(my $fh, $e_file) or die "Failed to open $e_file: $!";
while (<$fh>) {
# collect counts of each [A-Z]{3}[0-9]{5} match in the %counts
# hash with the match being a kay in this hash and the number
# of occurrences of this match being the value
$counts{$1}++ foreach /([A-Z]{3}[0-9]{5})/g;
}
# iterate through the first 15 top encountered matches
foreach my $key (
(
sort {$counts{$b} <=> $counts{$a}} keys %counts # sort dictionary keys
# in value descending order
)[0..14] # take first 15 items of the ordered list
)
{
print "$key $counts{$key}\n";
}
Demo: https://ideone.com/eN1AyJ
I need to input a number of lines and a single character to use for the reverse pyramid.The output must look like the following:
Maximum number of characters in a line : 6
Enter Echo Character : $
$$$$$$
$$$$$
$$$$
$$$
$$
$
This is what I have so far:
print "Maximum number of characters in a line : ";
$size = <>;
print "Enter Echo Character : ";
$character = <>;
chomp($size);
Loop: for $row (1 .. $size)
{
for $column (1 .. ($size+1))
{
if ($column < $row)
{
print "\n";
next Loop;
}
print $character;
}
}
But I am definitely doing something wrong because I cannot get the output I need after a couple hours of trying. I am new at Perl and any help I can get is definitely appreciated.
KMBP:Assignment 13 mypc$ perl pyramidtest.pl
Maximum number of characters in a line : 6
Enter Echo Character : $
$
$
$
$
$
$
$
KMBP:Assignment 13 mypc$
The x operator is also useful for this.
use feature qw(say);
print 'character? ';
chomp(my $char = <STDIN>);
print 'length? ';
chomp(my $length = <STDIN>);
while ($length) {
say $char x $length;
$length--;
}
Why are you setting $row from 1 .. $size if you want a reverse pyramid?
Why are you setting the end of the range for $column to $size + 1 instead of $row?
Why do you have some kind of strange logic for determining when to print a newline?
use strict;
use warnings;
print "Maximum number of characters in a line : ";
chomp(my $size = <>);
print "Enter Echo Character : ";
chomp(my $character = <>);
while ($size) {
for (1 .. $size) {
print $character;
}
print "\n";
$size--;
}
Note: you probably want to validate that $size is a positive integer, or else you might get unexpected results for certain inputs!
I'm trying to calculate the percentage of certain characters in a string from a file that is in FASTA format. So the file looks like this;
>label
sequence
>label
sequence
>label
sequence
I'm trying to calculate the percentage of specific characters (e.g G's) from the "sequence" strings.
After calculating that (which I have been able to do), I'm trying to print a sentence that says: "The percentage of G's in (e.g.) label 1 is (e.g)53%".
So my question really is, how do I do a calculation on the sequence strings and then name each one in its corresponding output by the label above it?
The code I have so far works out the percentage but I have no way of identifying it.
#!/usr/bin/perl
use strict;
# opens file
my $infile = "Lab1_seq.fasta.txt";
open INFILE, $infile or die "$infile: $!\n";
# reads each line
while (my $line = <INFILE>){
chomp $line;
#creates an array
my #seq = split (/>/, $line);
# Calculates percent
if ($line !~ />/){
my $G = ($line =~ tr/G//);
my $C = ($line =~ tr/C//);
my $total = $G + $C;
my $length = length($line);
my $percent = ($total / $length) * 100;
#prints the percentage of G's and C's for label is x%
print "The percentage of G's and C's for #seq[1] is $percent\n";
}
else{
}
}
close INFILE
It spits out this output (below) when I'm really trying to get it to also say the name of each label that corresponds to the sequence
The percentage of G's and C's for is 53.4868841970569
The percentage of G's and C's for is 52.5443110348771
The percentage of G's and C's for is 50.8746355685131
You just need to match your label and save that in a variable:
my $label;
# reads each line
while (my $line = <INFILE>){
...
if ($line =~ />(.*)/){
$label = $1;
# Calculates percent
} else{
...
print "The percentage of G's and C's for $label, #seq[1] is $percent\n";
}
}
I am needing to obtain the algorithm used in this little bit of Perl code, but I know nothing about Perl. Usually that's not a problem since I will research the language, but this regular expression stuff is way over my head!
Could anybody pseudo-code this? I just need to know what's going on so I can implement it in something else, preferably PHP or even C++, but I'll worry about that part. I just need to somehow decipher what this is doing:
$a = $ARGV[0];
$a =~ s/[^A-F0-9]+//simg;
#b = reverse split /(\S{2})/,$a;
$c = join "", #b;
$c .= "0000";
$d = hex($c) % 999999929;
print "$d\n";
What's poorly written about it? It could use a better var names, but I don't know if that's possible (since the intermediary steps don't appear to have any nameable quality), leaving only an improper use of split. The pseudo code is almost a word for word translation.
$a = $ARGV[0];
$a =~ s/[^A-F0-9]+//simg;
#b = reverse split /(\S{2})/,$a;
$c = join "", #b;
$c .= "0000";
$d = hex($c) % 999999929;
print "$d\n";
should be
$a = $ARGV[0]; # Get a hex str from cmd line E3:C9:D4
$a =~ s/[^A-F0-9]+//simg; # Remove any non-hex digits E3C9D4
#b = reverse $a =~ /(..)/sg; # Extract "bytes"; reverse D4, C9, E3
$c = join "", #b; # Join them. D4C9E3
$c .= "0000"; # Append two NULs D4C9E30000
$d = hex($c) % 999999929; # Convert from hex to number and modulus
print "$d\n"; # Print the result (in decimal).
Slightly clearer:
$a = $ARGV[0];
$a =~ s/[^0-9A-Fa-f]+//g;
$a = join '', reverse $a =~ /(..)/sg;
$a .= "0000";
$a = hex($a);
$a %= 999999929;
print "$a\n";
There might be a bug in these snippets. On a Perl with 32-bit ints, hex will overflow if the input has more than four hex digits. A Perl with 64-bit ints will handle 12 hex digits.
You seem to have taken the code from here. It's meant to take a MAC address as input, meaning the code requires 64-bit integers or Math::BigInt to work. There's no way around it since you want to modulus a 64-bit value.
Here's a concise way to do it that only works on Perls with 64-bit integers:
my $mac = $ARGV[0];
$mac =~ s/[^0-9A-Fa-f]+//g;
die length($mac) != 12;
# "123456789ABC" => 0xBC9A785634120000
my $hash = unpack('Q<', pack('H*', "0000$mac"));
$hash %= 999999929;
print "$hash\n";
For portability, you're better off integrating Math::BigInt into the earlier version.
It's looking for a bunch octets in hex concatenated together as the first argument of the program, and applying modulus.
So, if the program is invoked as:
$ myprog.pl A0B0
then the value in $c will be B0A00000. Therefore, the value of $d should be 0x396A6C8E.
It is a particularly bad piece of code written by someone who is scared of pack and unpack.
$a = $ARGV[0]; # assign first command line arg to $a
$a =~ s/[^A-F0-9]+//simg; # delete non-hex from $a
#b = reverse split /(\S{2})/,$a; # split $a by 2 non-whitespace (saving them too) to array #b and reverse it
$c = join "", #b; # join array #b to scalar $c
$c .= "0000"; # append 4 zeros to $c
$d = hex($c) % 999999929; # get modulo
print "$d\n"; # print it
$a = $ARGV[0]; #Read in the first argument on the command line
$a =~ s/[^A-F0-9]+//simg; #Substitute non hex numbers with nothing *
#b = reverse split /(\S{2})/,$a; #What is left in $a, split by 2 non-space characters
$c = join "", #b; # put the array b into $c
$c .= "0000";
$d = hex($c) % 999999929; #Convert $c to an integer and % with 999999929
print "$d\n";
simg = i: case insensitive; g: global; m: multi-line; s: single-line;
In short, we are stripping off the first hex number, then reversing the order of bytes (2 hex numbers at a time) and doing a modulo on the result.
How would I go about sorting across multiple columns for the below code?
Currently, the code:
1. Gets a #list of files in a $directory
2. Uses regex to get the $fileName, $fileLocation and $fileSize for each element in #list
3. Prints out the 3 values in (2) into 3 fixed-width columns
4. Then prints out the total number of files and directory size
I would like the output to display sorted by:
1. $fileName then
2. $fileLocation then
3. $fileSize
$directory = '/shared/tmp';
$count = 0;
#list = qx{du -ahc $directory};
printf ("%-60s %-140s %-5s\n", "Filename", "Location", "Size");
foreach(#list) {
chop($_); # remove newline at end
if (/^(.+?K)\s+(.+\/)(.+\.[A-Za-z0-9]{2,4})$/) { # store lines with valid filename into new array
# push(#files,$1);
$fileSize = $1;
$fileLocation = $2;
$fileName = $3;
if ($fileName =~ /^\./) {
next; }
printf ("%-60s %-140s %-5s\n", $fileName, $fileLocation, $fileSize);
$count++;
}
else {
next;
}
}
print "Total number of files: $count\n";
$total = "$list[$#list]";
$total =~ s/^(.+?)\s.+/$1/;
print "Total directory size: $total\n";
You can specify your own sorting algorithm and give it to sort!
Documention: sort - perldoc.perl.org
A sample implementation
Push your results (in a hash reference) into an array called #entries, and use something like the below.
my #entries;
...
# inside your loop
push #entries, {
'filename' => $fileName,
'location' => $fileLocation,
'size' => $fileSize
};
...
my #sorted_entries = sort {
$a->{'filename'} cmp $b->{'filename'} || # use 'cmp' for strings
$a->{'location'} cmp $b->{'location'} ||
$a->{'size'} <=> $b->{'size'} # use '<=>' for numbers
} #entries;