awk includes carriage return (CR) characters

Viewed 91

I have a textfile with a bunch of data and lines like SID: 1 - SN: 0123456789 scattered all over the file. All lines are delimited with CR/LF (Windows)
In bash I create an array with unique Serial Numbers:

sn=($(cat ./serials |awk '/SN: / { print $3 }' FS=': '|sort -u;))

So far so good, but each array member contains a CR at the end:

echo "${sn[0]}:test"

prints :test56789 instead of 0123456789:test

I can fix it with tr -d '\r' like this:

sn=($(cat ./serials |tr -d '\r'|awk '/SN: / { print $3 }' FS=': '|sort -u;))

but I doubt if this is the best approach. Is there a way to remove the CR in the awk command?

2 Answers

Is there a way to remove the LF in the awk command?

Sure you can have awk like this:

awk -F ': *' '{sub(/\r$/, "")} /SN: / {print $3}' serials

Your complete solution to read awk output into a bash array:

readarray -t sn < <(
awk -F ': ' '{sub(/\r$/, "")} /SN: / {print $3}' serials | sort -u)

# check bash array
declare -p sn

3 approaches of the same idea, tested and working on mawk, gawk, and nawk

awk '++_[$!++NF]<--NF' FS='^.* SN: ' OFS= RS='\r?\n'
awk '!_[$!++NF]++<--NF'
awk 'NF>++_[$(NF=NF)]'

No risk of decrementing NF to negative zone, because the incrementing action precedes it.

Related