Difference in awk output and while

so, im going over one of my scripts and trying to optimize it.

i have a code like this:

cksum sjreas.py | awk '{prinnt $1$2}'

This does what I need. However, i dont want to call the external command awk. so im doing this:

cksum sjreas.py | while OFS=' ' read v1 v2 ; do printf "${v1}${v2}"; done

The problem is, the while loop seems to have a problem with the spaces. When i tell it above to grab only the first two values from the output of cksum, it also grabs the space that's right after v2.

Is there a way to make the while loop operate exactly like awk and only grab the field you tell it to grab?

btw, the output of cksum, without while or awk being used is this:

3558287950 577 sjreas.py

Since you call the external cksum command, I do not see the value of losing the call to awk ... unless you have this code execute hundreds of times in a loop we did not see.

while read v1 v2 v3 
do
    echo "$v1$v2"
done < cksum sjreas.py
# or
 declare -a arr=(`sjreas.py`)   # use backticks it is clearer IMO
# you now have an array
echo "${arr[0]}${arr[1]}"
1 Like

If you are using bash, ksh93 or zsh, you could do something like this

read v1 v2 dummy < <(cksum sjreas.py)

---
The reason you get a trailing space in your variable may also be because of the value that you used for IFS.

1 Like

You've got two things deserving comments in above:

  • the OFS variable has a meaning in awk (only / mostly). for shell, use IFS .
  • as your v2 variable holds the remainder of the input line, i.e. 577 sjreas.py , I'd be surprised if the printf command only outputted a space, and not the file name, because, due to the quoting, everything would be the first parameter to printf and thus its "format string".

You can also remove the filename from the output of cksum :

$ cksum file
812788392 1423 file
$ cksum < file
812788392 1423

Obviously you cannot do this if getting the checksum of multiple files.

Andrew

1 Like