Extract the n-th field from a single line of comma separated values

IFS=, read -r first_name _ city _ <<< "John,Doe,New York,Times Square"

August 31, 2023bashoneliners

Explanation

read is a shell builtin to read fields from standard input into variables.

The -r flag makes the command use "raw" mode, which means the input values will be stored in variables without any modifications, for example without applying escape sequences using \.

This example specified 4 variables to store field values: first_name, _, city, and _ again. The name _ is customary for unused values. In this example we're only interested in the 1st and the 3rd fields, that's why we gave them proper names, and called the others simply _.

When there are more fields in the input than the number of variables, all remaining fields are stored in the last variable. This is why we couldn't simply use first_name _ city without an extra _ at the end, because this way the 4th and further fields would all end up in city.

read reads from standard input. To pass it the fixed text "John,Doe,New York,Times Square" we used the <<< operator, making this expression a so-called here-string. For more details see man bash and search for Here Strings.

Finally, to use , as the field separator, we prefixed the call to read with IFS=,. This sets IFS only for the read command, its value in the current shell is unchanged.

The technique is similar to cut -d, -f1,3 <<< "John,Doe,New York,Times Square", but significantly faster, because read is a builtin, and cut is an external program. Using builtins instead of commands is especially important within loops.