2 Apparently #air doesn't exist in Vanilla. Weird.
source | link

Duplicating commands is a common thing, because there is no "OR" in commands.

Another thing that is also called "tag" (not to be confused with NBT tags, the tags that were formerly a part of the scoreboard command, name tags, the "tag" NBT tag of items or the German word for "day") can help for your second case. Simply check for "#air" instead of "air", that makes it use the built-in block tag that matches air, cave air and void air. There are also entity tags and function tags and you can define your own in datapacks.

In your first case you might be able to do something like "as @e[type=villager] unless entity @s[tag=block1] unless entity @s[tag=block2]" or other fancy tricks, but if that doesn't work in your case, then yes, you might need to use another tag (just "tag" this time, the not-scoreboard-anymore type). You can also do very fancy things, like custom predicates (in 1.15), but that's not worth it for such a small example.

Another thing that is also called "tag" (not to be confused with NBT tags, the tags that were formerly a part of the scoreboard command, name tags, the "tag" NBT tag of items or the German word for "day") can help for your second case. If you create a block tag (archive) with the name air and then check for "#air" instead of "air", you can match all blocks in that tag at once. Don't forget the namespace if your datapacks uses a different one than minecraft.

Duplicating commands is a common thing, because there is no "OR" in commands.

Another thing that is also called "tag" (not to be confused with NBT tags, the tags that were formerly a part of the scoreboard command, name tags, the "tag" NBT tag of items or the German word for "day") can help for your second case. Simply check for "#air" instead of "air", that makes it use the built-in block tag that matches air, cave air and void air. There are also entity tags and function tags and you can define your own in datapacks.

In your first case you might be able to do something like "as @e[type=villager] unless entity @s[tag=block1] unless entity @s[tag=block2]" or other fancy tricks, but if that doesn't work in your case, then yes, you might need to use another tag (just "tag" this time, the not-scoreboard-anymore type). You can also do very fancy things, like custom predicates (in 1.15), but that's not worth it for such a small example.

Duplicating commands is a common thing, because there is no "OR" in commands.

In your first case you might be able to do something like "as @e[type=villager] unless entity @s[tag=block1] unless entity @s[tag=block2]" or other fancy tricks, but if that doesn't work in your case, then yes, you might need to use another tag. You can also do very fancy things, like custom predicates (in 1.15), but that's not worth it for such a small example.

Another thing that is also called "tag" (not to be confused with NBT tags, the tags that were formerly a part of the scoreboard command, name tags, the "tag" NBT tag of items or the German word for "day") can help for your second case. If you create a block tag (archive) with the name air and then check for "#air" instead of "air", you can match all blocks in that tag at once. Don't forget the namespace if your datapacks uses a different one than minecraft.

1
source | link

Duplicating commands is a common thing, because there is no "OR" in commands.

Another thing that is also called "tag" (not to be confused with NBT tags, the tags that were formerly a part of the scoreboard command, name tags, the "tag" NBT tag of items or the German word for "day") can help for your second case. Simply check for "#air" instead of "air", that makes it use the built-in block tag that matches air, cave air and void air. There are also entity tags and function tags and you can define your own in datapacks.

In your first case you might be able to do something like "as @e[type=villager] unless entity @s[tag=block1] unless entity @s[tag=block2]" or other fancy tricks, but if that doesn't work in your case, then yes, you might need to use another tag (just "tag" this time, the not-scoreboard-anymore type). You can also do very fancy things, like custom predicates (in 1.15), but that's not worth it for such a small example.