How to Check If Awk Array Is Empty

how to check if awk array is empty

Check it with length() function:

if ( length(sourceAndRestricted) > 0 ) {
printf "\t\t"var"\n"
}
else
print "NONE"
}

How to check if the variable value in AWK script is null or empty?

The comparison with "" should have worked, so that's a bit odd

As one more alternative, you could use the length() function, if zero, your variable is null/empty. E.g.,

if (length(val) == 0)

Also, perhaps the built-in variable NF (number of fields) could come in handy? Since we don't have access to your input data it's hard to say though, but another possibility.

Check if an awk array contains a value

Awk noob here. I digested Steven's answer and ended up with this hopefully easier to understand snippet below. There are 2 more subtle problems:

  • An Awk array is actually a dictionary. It's not ["value1", "value2"], it's more like {0: "value1", 1: "value2"}.
  • in checks for keys, and there is no built-in way to check for values.

So you have to convert your array (which is actually a dictionary) to a dictionary with the values as keys.

BEGIN {

split("value1 value2", valuesAsValues)
# valuesAsValues = {0: "value1", 1: "value2"}

for (i in valuesAsValues) valuesAsKeys[valuesAsValues[i]] = ""
# valuesAsKeys = {"value1": "", "value2": ""}
}

# Now you can use `in`
($1 in valuesAsKeys) {print}

For one-liners:

echo "A:B:C:D:E:F" | tr ':' '\n' | \
awk 'BEGIN{ split("A D F", parts); for (i in parts) dict[parts[i]]=""} $1 in dict'

AWK array seems to empty itself?

You are incrementing b at the end of the first iteration of your for (i in rows) loop because i == 0 ==> i%5 == 0, while you want to do it at the end of the 5th iteration. Try if (i%5 == 4) ++b.

Note that as you use GNU awk you could simplify all this. When the record separator (RS) is the empty string the records are separated by empty lines (one record per board):

$ awk -v RS='' '
NR>1 {
a[NR-2][1]; split($0, a[NR-2]);
}
END {
for(b in a) for(r in a[b])
boards[b][int((r-1)/5)][(r-1)%5] = a[b][r];
for(b in boards) for(r in boards[b]) for(n in boards[b][r])
print b, r, n, boards[b][r][n]
}' ex.txt
0 0 0 22
0 0 1 13
0 0 2 17
0 0 3 11
0 0 4 0
0 1 0 8
...

How can I get the length of an array in awk?

When you split an array, the number of elements is returned, so you can say:

echo "hello world" | awk '{n=split($0, array, " ")} END{print n }'
# ------------------------^^^--------------------------------^^

Output is:

2

Why does awk not in array work just like awk in array?

I cannot find any doc about element not in array.

Try !(element in array).


I guess: awk sees not as an uninitialized variable, so not is evaluated as an empty string.

$1 not == $1 "" == $1

How to test value is inside array with awk

awk stores arrays differently then what you expect. It's a key/value pair with the key (from split() is the integer index starting at 0 and the value is the string that was split() it into that element.

The awk in condition tests keys, not values. So your "U+4E00" in boundaries condition isn't going to pass. Instead you'll need to iterate your array and look for the value.

for (boundary in boundaries) { if(boundaries[boundary] == "U+4E00") { print "inside" }

Either that or you can create a new array based on the existing one, but with the values stored as the key so the in operator will work as is.

for (i in boundaries) {boundaries2[boundaries[i]] = ""}
if ("U+4E00" in boundaries2){print "inside"}

This second method is a little hackey since all your element values are set to "", but it's useful if you are going to iterate through large file and just want to use the in operator to test that a field is in your array (as opposed to iterating the array on each record, which might be more expensive).

Issue with AWK array length?

Well, I found an answer to my own problem:

I wonder how I missed it, but nullifying the array at the end of each initiation is always critical for repeated usage of same array name (no matter which language/ script one uses).

correct awk was:

cat filename | awk -F "\t" '{i=0;med=0;for(i=2;i<=NF;i++) array[i]=$i;asort(array);print length(array);delete array}'

how to create an empty array

Summary

The idiomatic method of creating an empty array in Awk is to use split().

Details

To simplify your example above to focus on your question rather than your typos, the fatal error can be triggered with:

BEGIN{
LINT = "fatal";
if (thread in threads_start) {
print "if";
} else {
print "not if";
}
}

which produces the following error:

gawk: cmd. line:3: fatal: reference to uninitialized variable `thread'

Giving thread a value before using it to search in threads_start passes linting:

BEGIN{
LINT = "fatal";
thread = 0;
if (thread in threads_start) {
print "if";
} else {
print "not if";
}
}

produces:

not if

To create a linting error with an uninitialised array, we need to attempt to access an non-existent entry:

BEGIN{
LINT = "fatal";
thread = 0;
if (threads_start[thread]) {
print "if";
} else {
print "not if";
}
}

produces:

gawk: cmd. line:4: fatal: reference to uninitialized element `threads_start["0"]'

So, you don't really need to create an empty array in Awk, but if you want to do so, and answer your question, use split():

BEGIN{
LINT = "fatal";
thread = 0;
split("", threads_start);
if (thread in threads_start) {
print "if";
} else {
print "not if";
}
}

produces:

not if



Related Topics



Leave a reply



Submit