0

I have been trying to get a maximum and a minimum value in the text file that have a numerical table. In order to do this, I opened up each column in the file using awk function for loop. But I got this error below. I am beginner to use awk, and I cannot find what the problem is. Please help me out!

I got stuck in this problem with:

awk: line 1 : syntax error at or near {
awk: line 1 : syntax error at or near }
awk: line 1 : syntax error at or near {
awk: line 1 : syntax error at or near }

This is my script:

#!/bin/bash
for i in {1..11}
do
    #print minimum value in the text file.
    awk -F' ' '{print ${i}}' [filename].txt | sort -n | head -1
    #print maximum value in the text file.
    awk -F' ' '{print ${i}}' [filename].txt | sort -n | tail -1
done
16
  • 3
    ${1} is not correct. Use $1 instead. I am not sure what you mean with [filename], by the way. It's syntactically correct, but it resolves either to a list of files with single-character names a, e, f, i, l, m or n, or to the literal string [filename]; none of which is likely to be your intention. Commented May 3, 2021 at 14:34
  • You could also use sort -n $filename | head -1 | cut -f1 -d' '. Or use awk's processing power for finding the maximum and minimum in one pass without head, tail and sort. Commented May 3, 2021 at 14:39
  • 1
    Why are you trying to reference $NF in the BASH part of the script? It rather looks like you are trying to loop through awk-parsed items outside the awk script. awk variables are completely separate from BASH variables.
    – kbulgrien
    Commented May 3, 2021 at 14:40
  • Another oddity: You loop $NF times, and in each loop you do exactly the same thing. You get the same output $NF times. As @kbulgrien says, you seem to be mixing Bash and awk. What does an input file look like? Commented May 3, 2021 at 14:43
  • 1
    *.txt isn't a filename. It's a glob that may or may not match one or more filenames. If your code refers to a single file I'd put a single file in there, e.g. example.txt Commented May 3, 2021 at 15:01

1 Answer 1

3

Given the structure of your shell script, I’m assuming you want to determine the minimum and maximum per column. This can be done entirely in AWK:

#!/usr/bin/awk -f
BEGIN { delete mins; delete maxs }
{
  for (i = 1; i <= NF; i++) {
    if (!(i in mins) || $i < mins[i]) mins[i] = $i
    if (!(i in maxs) || $i > maxs[i]) maxs[i] = $i
  }
}
END {
  for (i = 1; i in mins; i++) printf("%d ", mins[i])
  print ""
  for (i = 1; i in maxs; i++) printf("%d ", maxs[i])
  print ""
}

The BEGIN lines initialises the empty arrays.

The second block processes each line, and within each line, each field. We check the current index against the arrays’ keys; if we haven’t yet stored a value, or if the value is smaller (for minima) or larger (for maxima) than the stored value, we update the value in the array.

The END block displays the result, looping over indexes.

2
  • 1
    Thanks! I hadn’t thought of checking the keys... I wanted to avoid referring to NF in the END section to allow for varying numbers of fields in each line. Commented May 4, 2021 at 11:00
  • Ah, I see, then yeah what you have now is the way to do it.
    – Ed Morton
    Commented May 4, 2021 at 11:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .