0

I need to keep only the 4 most recent file in a directory. I used the following command:

rm -f `ls -t $SOMEDIR/archive/* | awk 'NR>4'`

That's working. I'd like to use a variable NUM_TO_KEEP instead of the '4', so I tried the following:

NUM_TO_KEEP=4
rm -f `ls -t $SOMEDIR/archive/* | awk -v num=$NUM_TO_KEEP 'NR>$num'`

And I get the following error: awk: syntax error near line 1 awk: bailing out near line 1

I also tried a simple ls | awk -v var="foo" 'NR>4'

And I get the same error. I am trying this on linux and solaris and get the same error for both OS. Any idea on what I'm doing wrong? My question is regarding the error I get while using the '-v' option, as soon as I set a variable next to the -v option I get an error. (ls | awk -v 'NR>4' works, ls | awk -v="foo" 'NR>4' gives an error)

Melodie Gauthier
  • 685
  • 3
  • 12
  • 35
  • 2
    Change `$num` to `num` in your awk script. – Tom Fenech Jan 18 '16 at 16:36
  • Not working to change $num to num, as soon as I put something next to -v I get the error.. – Melodie Gauthier Jan 18 '16 at 16:42
  • 1
    BTW, a less error-prone way to do this (which is to say, one that doesn't allow files to have names that prevent them from ever being successfully cleaned up) is to use `find` to print a NUL-delimited stream of epoch-time/filename pairs, do a numeric sort on that stream, and kill all but the first four elements of it. Parsing `ls` is considered a code smell for a reason. – Charles Duffy Jan 18 '16 at 16:43
  • ...see http://mywiki.wooledge.org/ParsingLs on that point. – Charles Duffy Jan 18 '16 at 16:44
  • 1
    As for what you're trying to do, http://stackoverflow.com/a/299911/14122 is a slightly-more-complicated-than-necessary implementation. – Charles Duffy Jan 18 '16 at 16:44
  • 1
    ...and http://stackoverflow.com/a/990575/14122 is another correct variant (it's a shame there are so many bad answers to an otherwise-topical question). – Charles Duffy Jan 18 '16 at 16:45
  • 1
    Thanks @EdMorton , it's the answer I was looking for. This means I can't use it since I have no control on the awk version users of this have. – Melodie Gauthier Jan 18 '16 at 17:30

1 Answers1

3

Although this has been referred to as a dup and those other similar questions do solve part of your problem (how to access a shell variables value in an awk script), the real reason you are getting the specific error message awk: syntax error near line 1 awk: bailing out near line 1 is that you are using old, broken awk (usr/bin/awk on Solaris) which produces that error message for most awk scripts, valid or otherwise. Use GNU awk if at all possible, otherwise on Solaris use /usr/xpg4/bin/awk (or nawk but it is less POSIX-compatible).

Absolutely no-one should be using old, broken awk, so do not restrict your code based on assuming someone might be using it. If they are then they need to update their PATH to not do that. I'm extremely surprised you found a version of it on linux, I thought only Solaris had it malingering around. If you are writing a shell script you can just make sure to skip over it in the PATH before awk is called, e.g. pseudo-code:

if (I'm on Solaris)
then
    AWK=/usr/xpg4/bin/awk
else
    AWK=$(which awk)
fi
$AWK -v x=y 'script' file

or:

if [ ! awk -v x=y '1' /dev/null >/dev/null 2>&1 ]
then
    AWK=$(which awk | tail -1)
else
    AWK=$(which awk)
fi
$AWK -v x=y 'script' file

or something else that tests for the first awk in your PATH being old, broken awk and if so skips it to a different awk

Ed Morton
  • 188,023
  • 17
  • 78
  • 185