How to make number in first line of file as variable? - perl

I have a file with a list of number like this:
10
15..135
140..433
444..598
600..783
800
The first and last lines are always single number without "..". So the problem is that, how to edit the first and last line to be like this:
1..10
15..135
140..433
444..598
600..783
800..900
For the first line.. I need to put "1.." in front of the number IF THE NUMBER IS NOT 0. If the number is already 0, no "1.." need to be there.
For last line.. I always want to edit (in this case I add "..900"). Can somebody give me some idea?

perl -pi -e '($.==1)?s/^/1../:((eof)?s/$/..900/:1);' your_file
PS: This does an in place replacement of the file

Related

If Line Number Exists

Im trying to get a code that will do something if a certain line number is in a text file for example "Test.txt"
Ex.
if line "x" exists in test.txt msg $chan working
thanks #denny for being the one to help me out.
if ($read(test.txt, n, x)) {
msg $chan working
}
You have couple of options.
Searching to see if the number is lower or equal to the total lines. e.g: $lines(filename)
You can extract the line and use a condition if it's full. e.g: $read(filename, LINE-NUMBER)
Notes for each method:
Will only tell you if there is a line number, NOT if there is something inside this line.
Will only give you the line if exists, if the line is empty or there is no such line then it will appears like it's empty.

Linux command to sort according to second word/character

I have a linux file whose content is as below:
hey this
is just
sample file
I want to :
1. sort the three lines according to the second word so the output should be :
sample file
is just
hey this
2. sort the three lines according to the second character of second line, so the output would be :
hey this
sample file
is just
Is there anyway i can run a perl/unix command on command line(doesnt matter using pipes)?
I got the answer for both the questions:
For sorting by second word: sort -k2 myfile
For sorting by second character of second word sort -k2.3 myfile

Replace text between brackets

This is the first time I've tried to do this from a Mac (I use repl.bat on Windows) and I'm struggling to figure out the correct syntax to do this.
Basically, I have in a file called defines.h that has stuff like this in it:
#define GAME_VERSION (2060)
#define TESTHOOK
#define PRERELEASE
#define pi 3.1415926536f
#define FX32_ONE (4096)
And I want to replace the text between the brackets or after the equals with a passed in environment variable (I also want to replace things like GAME_VERSION= in other files)
I've been trying to use sed, perl and awk but can't seem to get the syntax right. Could someone talk me through this please?
I have managed to do this so far:
echo "GAME_VERSION (2000)" | sed s/'([^)]*)'/'3000'/g
The first 2 replies haven't changed the defines.h file at all and I'm not sure if I'm doing something else wrong or because I didn't show more of the file's contents before. Not sure if relevant but the contents of defines.h get printed to the terminal console also.
in thios specific case
NewValue=713705
sed "/^[[:space:]]*GAME_VERSION/ s/[0-9]*/${NewValue}/" define.h
assuming:
there are more than 1 line in define.h that can have number assigned
there is only 1 uncommented for GAME_VERSION
That should work with both formats:
REPLACE="5000"
sed "s/\([(=]\)\([0-9]\+\)/\1$REPLACE/g" defines.h
Gives the output:
GAME_VERSION (5000)
GAME_VERSION=5000
It searches for a bracket or a equal sign ([(=]) followed by a digit ([0-9]\+) and replaces it by the contentss of the environment variable $REPLACE.

creating a hash with regex matches in perl

Lets say i have a file like below:
And i want to store all the decimal numbers in a hash.
hello world 10 20
world 10 10 10 10 hello 20
hello 30 20 10 world 10
i was looking at this
and this worked fine:
> perl -lne 'push #a,/\d+/g;END{print "#a"}' temp
10 20 10 10 10 10 20 30 20 10 10
Then what i need was to count number of occurrences of each regex.
for this i think it would be better to store all the matches in a hash and assign an incrementing value for each and every key.
so i tried :
perl -lne '$a{$1}++ for ($_=~/(\d+)/g);END{foreach(keys %a){print "$_.$a{$_}"}}' temp
which gives me an output of:
> perl -lne '$a{$1}++ for ($_=~/(\d+)/g);END{foreach(keys %a){print "$_.$a{$_}"}}' temp
10.4
20.7
Can anybody correct me whereever i was wrong?
the output i expect is:
10.7
20.3
30.1
although i can do this in awk,i would like to do it only in perl
Also order of the output is not a concern for me.
$a{$1}++ for ($_=~/(\d+)/g);
This should be
$a{$_}++ for ($_=~/(\d+)/g);
and can be simplified to
$a{$_}++ for /\d+/g;
The reason for this is that /\d+/g creates a list of matches, which is then iterated over by for. The current element is in $_. I imagine $1 would contain whatever was left in there by the last match, but it's definitely not what you want to use in this case.
Another option would be this:
$a{$1}++ while ($_=~/(\d+)/g);
This does what I think you expected your code to do: loop over each successful match as the matches happen. Thus the $1 will be what you think it is.
Just to be clear about the difference:
The single argument for loop in Perl means "do something for each element of a list":
for (#array)
{
#do something to each array element
}
So in your code, a list of matches was built first, and only after the whole list of matches was found did you have the opportunity to do something with the results. $1 got reset on each match as the list was being built, but by the time your code was run, it was set to the last match on that line. That is why your results didn't make sense.
On the other hand, a while loop means "check if this condition is true each time, and keep going until the condition is false". Therefore, the code in a while loop will be executed on each match of a regex, and $1 has the value for that match.
Another time this difference is important in Perl is file processing. for (<FILE>) { ... } reads the entire file into memory first, which is wasteful. It is recommended to use while (<FILE>) instead, because then you go through the file line by line and keep only the information you want.

perl sequence extraction loop

I have an existing perl one-liner (from the Edwards lab) that works wonderfully to read a text file (named ids.file) that contains one column of IDs and searches a second, specially formatted text file (named fasta.file in this example - in "fasta" format for those who know bioinformatics) and returns sequences that match the ID from the first file. I was hoping to expand this script to do two additional things:
The current perl one-liner only seems to work if the ids.file contains one column of data. I would like it to work on a file that contains two columns (separated by spaces), and act on the second column of data (well, really any column of data, but I assume that it will be obvious enough to adapt it if someone can give an example using a second column)
I would like to append the any results returned from the output of the search to a third column, instead of just to a new file.
If someone is kind enough to offer an example but only has time or inclination to work on one of these, I would prefer that you try to solve #2 - I have come close to solving #1 with a for loop that uses awk to only use the Perl code on the second column - I haven't gotten it yet, but am close, so #2 seems like the harder one to me.
The perl one liner is as follows:
perl -ne 'if(/^>(\S+)/){$c=$i{$1}}$c?print:chomp;$i{$_}=1 if #ARGV' ids.file fasta.file
I appreciate any help you can give!
Not quite sure but will this do?
perl -ne 'chomp; s/^>(\S+).*/$c=$i{$1}/e; print if $c;
$i{(/^\S*\s(\S*)$/)[0]}="$_ " if #ARGV'
ids.file fasta.file