Reputation: 23
I have an assigment that asks me to print on screen the number of words that are longer than a given number ,let's say k , which is read from the keyboard. and then to order the result. Until now I decided to try in this way :
#!bin/bash
k=0
if [ $# -eq 0 ]
then
echo "No argument supplied."
exit 1
fi
echo -n "Give the minimal lenght of the words : "
read k
for files in "$@"
do
if [ -f "$files" ]; then
echo "$(cat $files | egrep -o '[^ ]{k,}' $files | wc -w) : $files."
else
echo "Error: File $files has not been found."
fi
done | sort -n
My issues is that whenever I try this program with k in the section "egrep -o '[^ ]{k,}'" it always gives a wrong answer. But if I replaced it with an integer, in works exactly as I wanted.
Which is the right way to make this code work for k read from keyboard? which is the syntax , can't really understand how I should write there , tried other ways to like "$k" , $k , ((k)) , k
.
Any help is welcome , a hint if someone could give me please? I am stuck
Upvotes: 2
Views: 58
Reputation: 439477
Try
echo "$(egrep -o '[^ ]{'"$k"',}' "$files" | wc -w): $files"
k
instead of $k
.
$
(by contrast, you mustn't use $
when assigning to it). In some cases, to separate the variable name from subsequent tokens, you must enclose the name in {..}
, e.g., ${k}
, which you may also opt to do for visual clarity, even when it's not strictly required.egrep
search regex (inside the command substitution), which prevents expansion of variable references.
$(...)
) are their own worlds, in which the usual parsing rules apply (single-quoted strings are literals, whereas double-quoted strings may have embedded variable references, command substitutions, arithmetic expansions).{...}
) inside a command substitution:
"[^ ]{$k,}"
. However, the solution presented works in both bash 3.x and 4.xk=3; echo "$(egrep -co "[^ ]{$k,}" <<<$'abc\nde')"
1
, but returns 0 2
, due to mistakenly applying brace expansion to {3,}
(resulting in two strings: egrep -co '[^ ]3'
and egrep -co '[^ ]'
), even though it is contained inside a double-quoted string.'[^ ]{'"$k"',}'
concatenates literal [^ ]{
with the value of variable $k
and literal ,}
. If $k
is 4
, for instance, egrep
then sees the following string: [^ ]{4,}
cat $files |
was unnecessary, since the file is also passed as an operand (non-option argument), and you should always double-quote variables containing filenames, so the command won't break with filenames with embedded spaces.)$files
to $file
to avoid confusion: in each iteration of the loop, you're only dealing with a single file.Upvotes: 1