Validate email addresses with JQ
In this article i will show you a handy one-liner that can do the following, read from stdin a text file with email addresses, verify that…
In this article i will show you a handy one-liner that can do the following, read from stdin a text file with email addresses, verify that the addresses are valid, and finally generate JSON output with the results on stdout, JSON the to go format for APIs so, generating JSON output is a very nice to have knowledge!
The one-liner
Here is the one-liner which does all the job, might seem complicated but it isnt, i will explain everything you need to know!
cat emails.txt | jq -Rn '[inputs | {"email": ., "valid": (test("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$")?)}]'- emails.txt is the file that will contain the email addresses, here is an example content
john.doe@example.com
invalid-email@
jane_smith123@domain.co.uk
user@domain
another.valid.email@sub.domain.com
no-at-symbol.com
valid.email@domain.orgjq -Rn-Rprocesses input as raw strings and not JSON, each line is a separate string.-nthis starts jq with a null input, allowing jq to create a JSON output.[inputs | {…}]input is a filter which reads all the input lines from stdin, the outer brackets[…]indicates that we create an array of objects.{“email”: ., “valid”: …}generates the json object for each email that will check, value ofvalidwill be generated by a “test” function that will verify with a regex if the address is valid or not.test(…)contains our regex that verifies of the email is valid or not^[a-zA-Z0-9._%+-]+: Matches the beginning of the string with one or more allowed characters before the@symbol.@[a-zA-Z0-9.-]+: Matches the@symbol followed by one or more allowed characters for the domain.\\.: Matches a literal dot. The backslash\\is used to escape the dot in the regex pattern.[a-zA-Z]{2,}$: Matches the top-level domain which must have at least two characters.?: Ensures thattestreturnsfalseinstead of an error if the input does not match the regex.
Running the one-liner
Lets now execute the one-liner vs our email.txt file, we can see that generates a very nice and readable JSON output for each email
cat emails.txt | jq -Rn '[inputs | {"email": ., "valid": (test("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$")?)}]'
[
{
"email": "john.doe@example.com",
"valid": true
},
{
"email": "invalid-email@",
"valid": false
},
...
...
...Conclusion
jq is a powerful tool, is like grep for json files, it can do a lot of staff and is super useful when you want quickly to perform validations, in a next article i will provide an example on how to use inotify to trigger the execution of a script upon a file creation.