Reputation: 407
I'm trying to read input from a file in bash, but want to discard the first line of a file because of the header rows in the CSV. The tail -n+2 "${csv}"
works by itself but when using the <
I am getting error:
syntax error near unexpected token `-n+2'
The code I'm trying to make work is:
while IFS=, read c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c23 c24
do
description[$i]="${c3}"
current_ip[$i]="${c10}"
new_ip[$i]="${c12}"
new_netmask[$i]="${c13}"
new_gateway[$i]="${c14}"
i=$i+1
done < tail -n+2 "${csv}"
Can someone please help provide a working form of < tail -n+2 "${csv}"
and explain the solution?
Upvotes: 0
Views: 55
Reputation: 532268
Instead of using tail
, just read directly from the file, but use a compound command ({...}
and two read
s to discard the first two lines.
{ read; read;
while IFS=, read ...; do
...
done
} < "$csv"
Upvotes: 1
Reputation: 295815
The easy answer here is to use process substitution:
while ... done < <(tail -n+2 "$csv")
This works because <(tail)
is replaced, by the shell, with a filename which connects to the output of tail
, either via a named pipe or, on platforms that support it, a /dev/fd
alias.
Thus, when run, this will become something like (pseudocode):
tail -n+2 "$csv" >/dev/fd/63 &
while ... done < /dev/fd/63
...or (and this latter is what you might do if trying to write this code for POSIX sh, or otherwise a shell without comparable functionality):
tempdir=$(mktemp -t -d csvpipe.d.XXXXXX)
mkfifo "$tempdir/csvpipe.tmp"
tail -n+2 "$csv" >"$tempdir/csvpipe.tmp" &
while ... done <"$tempdir/csvpipe.tmp"
rm -rf "$tempdir"
...though your shell won't need the overhead of a temporary directory to use in creating its FIFO, this is somewhat safer than using mktemp -u
, and far safer than a fixed/hardcoded temporary file name.
Upvotes: 4