-1

good morning, I am a newbie in the world of scripts and I have this problem and I don't know why it happens to me and why I have it wrong, thanks in advance.

For example, I have this command that searches for users with X less letters:

cut -d: -f1 /etc/passwd | awk 'length($1) <= 4'

It works correctly but when I substitute a 4 for a variable with the same value it doesn't do it well:

number=4
echo -e $(cut -d: -f1 /etc/passwd | awk 'length($1) <= $number')

The same error happens to me here too, when I search for users who have an old password

awk -F: '{if($3<=18388)print$1}' < /etc/shadow

Works, but when I use the variable it stops working

variable=18388
awk -F: '{if($3<=$variable)print$1}' < /etc/shadow
Andrea
  • 5
  • 2

3 Answers3

2

Consider using awk's ability to import variables via the -v option, eg:

number=4
cut -d: -f1 /etc/passwd | awk -v num="${number}" 'length($1) <= num'

Though if the first field from /etc/passwd contains white space, and you want to consider the length of the entire field, you should replace $1 with $0, eg:

number=4
cut -d: -f1 /etc/passwd | awk -v num="${number}" 'length($0) <= num'

Even better, eliminate cut and the subprocess (due to the pipe) and use awk for the entire operation by designating the input field separator as a colon:

number=4
awk -F':' -v num="${number}" 'length($1) <= num { print $1 }' /etc/passwd
markp-fuso
  • 28,790
  • 4
  • 16
  • 36
1

You need to use double quotes:

echo -e $(cut -d: -f1 /etc/passwd | awk "length(\$1) <= $number")

In single quotes, variables are not interpreted.

Updated: Here is an illustrative example:

> X=1; echo '$X'; echo "$X"
$X
1

Update 2: as rightfully pointed out in the comment, when using double quotes one need to make sure that the variables that are meant for awk to interpret are escaped, so they are not interpreted during script evaluation. Command updated above.

Christian Fritz
  • 20,641
  • 3
  • 42
  • 71
0

Alternatively, this task could be done using only a single GNU sed one-liner:

num=4
sed -E "s/:.*//; /..{$num}/d" /etc/passwd

Another one-liner, using only grep would be

grep -Po "^[^:]{1,$num}(?=:)" /etc/passwd

but this requires a grep supporting perl regular expressions, for the lookahead construct (?=...).

M. Nejat Aydin
  • 9,597
  • 1
  • 7
  • 17