How do I use the firstLine argument in eachLine - groovy

I can't seem to make eachLine skip the first line, according to this there is an integer argument that can be passed to eachLine but I can't figure out the syntax
http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/File.html#eachLine(int, groovy.lang.Closure)
#doesn't work
new FileReader('myfile.txt').eachLine firstLine=2,{
line-> println line
}
#nope
new FileReader('myfile.txt').eachLine(2){
line-> println line
}

I think you are misunderstanding what the 'firstLine' parameter is used for. From the docs:
firstLine - the line number value used for the first line
Basically this means that this number will identify what the first line is. It always goes through each line in the file.
So for the following code:
new FileReader('c:/users/chris/desktop/file.txt').eachLine(4){line, number->
println "$number $line"
}
It would print out:
4 line1
5 line2
6 line3

To skip first line use return. It's works like continue in standard loops.
new FileReader('myfile.txt').eachLine { line, number ->
if (number == 1)
return // continue
println "$number: $line"
}

To expand upon #Michal's answer, for a general case (as opposed to a single line), you could do:
linesToSkip = 100
someFile.eachLine { line, lineNumber ->
if (lineNumber < linesToSkip) { return } // Skip previously read lines
println "${line}"
}

i was used readline x times before;
def arq = new FileReader('c:/users/chris/desktop/file.txt')
(0..4).each{
arq.readLine();
}
arq.eachLine{line, number->
println "$number $line"
}

Related

perl script adds extra curly brackets

Following script, I'm using which performs everything well except it adds three extra curly brackets at the end of file.
abc.jso contains many lines where few lines have only opening/closing curly brackets (In case, this information helps)
I tried by making print $a " $var"; instead of print $a "$var";. In short I added space in front of this print & it worked.
open (my $a,'+<',"abc.jso") or die $!;
my #lines=<$a>;
seek $a,0,0;
while (#lines) {
my $var = shift #lines;
if ($var=~ /^\s*\"(netlist|filelist)\" : \".*$blk.*\",/) {
print $a " \"netlist\" : \"/t98/pnr/work/$blk"."_rk/run/dc/$blk"."_post_dft.v\",\n";
$count++;
print "Netlist got replaced\n";
}
elsif ($var=~ /^\s*\"spf\" : \".*$blk.*\"/) {
print $a " \"spf\" : \"/t98/scan/atpg/t98_1.0/spf/$blk".".scan_compress.spf\"\n";
$count++;
print "SPF got replaced\n";
}
else {
print $a "$var";
}
}
close($a);
Can someone explain, why it is happening? Is there any such corner case of text handling that I'm not aware of?
Having some sample input and output would help but let me take a guess. Try truncating the file by the seek:
truncate $a,0;
seek $a,0,0;
Without the truncate you will be overwriting what was there before. This works if you write more information than you read but not so good if you write less than you read.

Get rid of warning in perl number adder code

I am writing a program that takes numbers from the command line until the user enters a blank line.
Should the user enter something that is neither newline nor numeric, it notifies the user, and continues.
While everything works, I have use warnings turned on, and it doesn't seem to like the second if conditional if the enters something invalid.
Argument "foo" isn't numeric in numeric eq (==) at adder.pl line 25, <STDIN> line 4.
I don't like running the program with this warning. How can I improve my code?
This is my program
#!/usr/bin/perl
use strict;
use warnings;
#declare variable
my $number = 0; #final answer
my $input;
#prompt the user
print "Input some integers, line by line. When you are done, press return to add them up." . "\n";
while (1) {
#get input from user
$input = <STDIN>;
#remove newlines
chomp($input);
#user pnches in newline
if ($input eq '') { #if the answer is new line
#quit the loop
last;
} #end of if statement
#user punches in bad input
elsif ($input == 0 && $input ne '0' && $input ne '') {
#tell the user what happened and how to rectify it
print "Input must be an integer." . "\n";
} # end of elsif statement
else {
chomp($input);
$number += $input;
} # end of else statement
} #end of while
print "Total is: $number\n";
Perl does DWIM very well. It is famous for it.
So, whatever language you have come from - it looks like C - forget about checking for both strings and numbers: a Perl scalar variable is whatever you ask it to be.
That means something like
elsif ($input == 0 && $input ne '0' && $input ne '') {
makes little sense. Anything read from the keyboard is initially a string, but it will be a number if you want. You are asking for $input to evaluate as zero but not to be the literal string 0. That applies to very few strings, for instance 00 or 0e0.
I think this is what you meant to write. Please take a look.
Isn't it clearer without comments?
use strict;
use warnings;
print "Input some integers line by line. When you are done, press return to add them up\n";
my $total = 0;
while (<>) {
chomp;
last unless /\S/;
if (/\D/) {
print "Input must be an integer\n";
next;
}
$total += $_;
}
print "Total is: $total\n";
Since Perl is untyped, and you are using $input as both a number and a string, you get that warning because "foo" isn't a number and "==" is used to compare equality of numbers.
You first need to check to see if $input is a number or not. One suggestion:
if ($input =~ /^\d+$/)
{
$number += $input;
}
else
{
print "Input must be an integer.\n";
}

Replacing values of a file based on a conf file

I have a conf file which has the format of variable="value" where values may have special characters as well. An example line is:
LINE_D="(L#'id' == 'log') AND L#'id' IS NULL"
I have another file F which should replace values based on this conf file. For example, if there is line in F
PRINT '$LINE_D'
it should be replaced by
PRINT '(L#'id' == 'log') AND L#'id' IS NULL'
How can I a program in shell script which takes conf and F and generate the values in F replaced.
Thanks
Your definition of what's required leaves lots of gaps, so you'll probably need to tweak this script. It is a cut-down version of a more complex script originally designed to process makefiles. That means there is probably material you could remove from here without causing trouble, though I've gotten rid of most of the extraneous processing.
#!usr/bin/env perl
#
# Note: this script can take input from stdin or from one or more files.
# For example, either of the following will work:
# cat config file | setmacro
# setmacro file
use strict;
use warnings;
use Getopt::Std;
# Usage:
# -b -- omit blank lines
# -c -- omit comments
# -d -- debug mode (verbose)
# -e -- omit the environment
my %opt;
my %MACROS;
my $input_line;
die "Usage: $0 [-bcde] [file ...]" unless getopts('bcde', \%opt);
# Copy environment into hash for MAKE macros
%MACROS = %ENV unless $opt{e};
my $rx_macro = qr/\${?([A-Za-z]\w*)}?/; # Matches $PQR} but ideally shouldn't
# For each line in each file specified on the command line (or stdin by default)
while ($input_line = <>)
{
chomp $input_line;
do_line($input_line);
}
# Expand macros in given value
sub macro_expand
{
my($value) = #_;
print "-->> macro_expand: $value\n" if $opt{d};
while ($value =~ $rx_macro)
{
print "Found macro = $1\n" if $opt{d};
my($env) = $MACROS{$1};
$env = "" unless defined $env;
$value = $` . $env . $';
}
print "<<-- macro_expand: $value\n" if $opt{d};
return($value);
}
# routine to recognize macros
sub do_line
{
my($line) = #_;
if ($line =~ /^\s*$/o)
{
# Blank line
print "$line\n" unless $opt{b};
}
elsif ($line =~ /^\s*#/o)
{
# Comment line
print "$line\n" unless $opt{c};
}
elsif ($line =~ /^\s*([A-Za-z]\w*)\s*=\s*(.*)\s*$/o)
{
# Macro definition
print "Macro: $line\n" if $opt{d};
my $lhs = $1;
my $rhs = $2;
$rhs = $1 if $rhs =~ m/^"(.*)"$/;
$MACROS{$lhs} = ${rhs};
print "##M: $lhs = <<$MACROS{$lhs}>>\n" if $opt{d};
}
else
{
print "Expand: $line\n" if $opt{d};
$line = macro_expand($line);
print "$line\n";
}
}
Given a configuration file, cfg, containing:
LINE_D="(L#'id' == 'log') AND L#'id' IS NULL"
and another file, F, containing:
PRINT '$LINE_D'
PRINT '${LINE_D}'
the output of perl setmacro.pl cfg F is:
PRINT '(L#'id' == 'log') AND L#'id' IS NULL'
PRINT '(L#'id' == 'log') AND L#'id' IS NULL'
This matches the required output, but gives me the heebie-jeebies with its multiple single quotes. However, the customer is always right!
(I think I got rid of the residual Perl 4-isms; the base script still had a few remnants left over, and some comments about how Perl 5.001 handles things differently. It does use $` and $' which is generally not a good idea. However it works, so fixing that is an exercise for the reader. The regex variable is not now necessary; it was when it was also recognizing make macro notations — $(macro) as well as ${macro}.)

Checking for Multiple Lines and Outputting what lines are missing. (Bash)

So basically I have a file, for the sake of understanding how to write this, that looks like this.
Start:
First line of text
Second line of text
Bin:
Third line of text
Four line of text
What I need to accomplish is write a script that checks for these strings and will output any missing strings.
Based on my assumptions I would assume this would involve an awk or grep that would check if each string and a set of if statements that would say if this doesn't exist then output what string doesn't exist.
Any pointers on how to start this?
Here's what I've tried so far with that is little psuedocode-ish.
`
str1=$(awk '/Start:/' /some/file)
str2=$(awk '/First line of text/' /some/file)
str3=$(awk '/Second line of text/' /some/file)
if $str1 == '' then
print $str1 'does not exist'
elif $str2 == '' then
print $str2 'does not exist'
else $str3 == '' then
print $str3 'does not exist'
fi` `
Something like this should print the missing strings with AWK:
BEGIN {
a[i++]="Start:"
a[i++]="First line of text"
a[i++]="Second line of text"
}
// {
for (s in a) {
if (match($0,a[s]) ) { a[s]="" }
}
}
END {
for (s in a) {
if (a[s] != "") { print a[s] }
}
}

Comparing Input to Strings

So I'm writing a relatively simple program that prompts the user for a command, add, subtract, etc, and then prompt for numbers to complete that operation. Everything is written and it compiles fine, but when I enter a command in (add, subtract, etc.) it isn't comparing it properly. Instead of entering the operation branch of the if case, it goes to the invalid command catch I added. Here is part of the code that contains the declaration and the first if statement.
my $command = <STDIN>;
my $counter = 1;
#perform the add operation if the command is add
if (($command eq 'add') || ($command eq 'a')){
my $numIn = 0;
my $currentNum = 0;
#While NONE is not entered, input numbers.
while ($numIn ne 'NONE'){
if($counter == 1){
print "\nEnter the first number: ";
}else{
print "\nEnter the next number or NONE to be finished.";
}
$numIn = <STDIN>;
$currentNum = $currentNum + $numIn;
$counter++;
}
print "\nThe answer is: #currentNum \n";
#perform the subtract operation if the command is subtract
}`
Does anyone know why if I enter in add it skips this?
$command probably still has the new line attached to it, so eq will fail. because "add" != "add\n"
You might consider just checking the first letter of your command, say with a regular expression
$command =~ /^a/i
or use chop on $command to remove the last character.
chop($command)

Resources