0

I have 2 files,

file1:

YARRA2

file2:

59204.9493055556    
59205.5930555556

So, file1 has 1 line and file2 has 2 lines. If file1 has 1 line, and file2 has more than 1 line, I want to repeat the lines in file1 according to the number of lines in file2. So, my code is this:

eprows=$(wc -l < file2)

awk '{ if( NR<2 && eprows>1 ) {print} {print}}' file1

but the output is

YARRA2

Any idea? I have also tried with

awk '{ if( NR<2 && $eprows>1 ) {print} {print}}' file1

but it is the same

anubhava
  • 761,203
  • 64
  • 569
  • 643
  • 1
    Please take a look at [How do I format my posts using Markdown or HTML?](https://stackoverflow.com/help/formatting). – Cyrus Jun 04 '22 at 19:15
  • Ed: Sorry I am going to reopen this because this is not just about passing shell variable to awk. Even if we add `-v eprows=5` OP's attempt will print only 2 lines instead of `4` – anubhava Jun 05 '22 at 06:14

3 Answers3

0

You may use this awk solution:

awk '
NR == FNR {
   ++n2
   next
}
{
   s = $0
   print;
   ++n1
}
END {
   if (n1 == 1)
      for (n1=2; n1 <= n2; ++n1)
         print s
}' file2 file1

YARRA2
YARRA2
anubhava
  • 761,203
  • 64
  • 569
  • 643
0
eprows=$(wc -l < file2)

awk '{ if( NR<2 && eprows>1 ) {print} {print}}' file1

Oops! You stepped hip-deep in mixed languages.

The eprows variable is a shell variable. It's not accessible to other processes except through the environment, unless explicitly passed somehow. The awk program is inside single-quotes, which would prevent interpreting eprows even if used correctly.

The value of a shell variable is obtained with $, so

echo $eprows
2

One way to insert the value into your awk script is by interpolation:

awk '{ if( NR<2 && '"$eprows"'>1 ) {print} {print}}' file1

That uses a lesser known trick: you can switch between single- and double-quotes as long as you don't introduce spaces. Because double-quoted strings in the shell are interpolated, awk sees

{ if( NR<2 && 2>1 ) {print} {print} }

Awk also lets you pass values to awk variables on the command line, thus:

awk -v eprows=$eprows '{ if( NR<2 && eprows >1 ) {print} {print}}' file1

but you'd have nicer awk this way:

awk -v eprows=$eprows 'NR < 2 && eprows > 1 { {print} {print} }' file1

whitespace and brevity being elixirs of clarity.

That works because in the awk pattern / action paradigm, pattern is anything that can be reduced to true/false. It need not be a regex, although it usually is.

James K. Lowden
  • 7,574
  • 1
  • 16
  • 31
  • That's a lot of prescription, Ed. I gave the OP some options and ways to think about the problem. I never quote shell variables unless I know they may include whitespace, because if there is unexpected whitespace, the quotes convert a syntax error to a semantic error. Here, `$eprows` must be an integer. If it's 2 strings, unquoted, **awk** will complain that it can't open the 2nd string as a file (or something), but, quoted, will run and always compare false. – James K. Lowden Jun 09 '22 at 15:31
  • You ignored my rationale. Are you really so sure of yourself that someone else's reasoned approach is invalid simply because you have his practice on your *never* list? – James K. Lowden Jun 09 '22 at 15:37
  • For anyone interested in the pros/cons of using unquoted variables, see [security-implications-of-forgetting-to-quote-a-variable-in-bash-posix-shells](https://unix.stackexchange.com/questions/171346/security-implications-of-forgetting-to-quote-a-variable-in-bash-posix-shells) (which provides references that address more than just the security issues) – Ed Morton Jun 09 '22 at 15:52
0

One awk idea:

awk '
FNR==NR { cnt++; next }                    # count number of records in 1st file

                                           # no specific processing for 2nd file => just scan through to end of file

END     { if (FNR==1 && cnt >=2)           # if 2nd file has just 1 record (ie, FNR==1) and 1st file had 2+ records then ...
             for (i=1;i<=cnt;i++)          # for each record in 1st file ...
                 print                     # print current (and only) record from 2nd file
        }
' file2 file1

This generates:

YARRA2
YARRA2
markp-fuso
  • 28,790
  • 4
  • 16
  • 36