Home > Back-end >  Argument in bash script
Argument in bash script

Time:04-30

I have the following bash script called countscript.sh

  1 #!/bin/bash
  2 echo "Running" $0
  3 tr -cs A-Za-z '\n' | tr A-Z a-z | sort | uniq -c | sort -rn | sed $1 q

But I don't understand how to pass the argument correctly: ( "3" should be the argument $1 of sed).

$ echo " one two two three three three" | ./countscript.sh 3
Running ./countscript.sh
sed: -e expression #1, char 1: missing command

This works fine:

    $ echo "one two three four one one four" | tr -cs A-Za-z '\n' | tr A-Z a-z | sort | uniq -c | sort -rn | sed 3q
  3 one
  2 four
  1 two

Thanks.

PS: Anybody else noticed the

bug in this script on page 10, https://www.cs.tufts.edu/~nr/cs257/archive/don-knuth/pearls-2.pdf ?

CodePudding user response:

In the quoted paper, I think you are misreading

sed ${1}q

as

sed ${1} q

and sed does not consider 3 by itself a valid command. The separate argument q is treated as an input file name. If the value of $1 did result in a single valid sed script, you would have likely gotten an error for the missing input file q.

Proper shell programming would dictate this be written as

sed "${1}q"

or

sed "${1} q"

instead; with the space as part of the script, sed correctly outputs the first $1 lines of input and exits.


It's somewhat curious that the authors used sed instead of head - "$1" to output the first few lines, as one of them (McIlroy) essentially invented the idea of the Unix pipeline as a series of special-purpose, narrowly focused tools. Not having read the full paper, I don't know what Knuth and McIlroy's contributions to the paper were; perhaps Bentley just likes sed. :)

CodePudding user response:

When running the following command:

$ echo " one two two three three three" | ./countscript.sh 3

the special variable $1 will be replaced by 3, your first argument. Hence, the script runs:

tr -cs A-Za-z '\n' | tr A-Z a-z | sort | uniq -c | sort -rn | sed 3 q

Notice the space between the 3 and the q. sed does not know what to do, because you give it no command (3 is not a command).

Remove the space, and you should be fine.

tr -cs A-Za-z '\n' | tr A-Z a-z | sort | uniq -c | sort -rn | sed "${1}q"
  •  Tags:  
  • bash
  • Related