When you iterate over the unquoted command substitution $(cat $file)
, you iterate over all words that cat $file
results in. A word will be anything delimited by a whitespace (space, tab or newline by default). This means that for a line in $file
that is
883427446627317909,1114259,1573178423,2019-11-08 02:00:23,RD,4.7,0,351442429
you will have the two words 883427446627317909,1114259,1573178423,2019-11-08
and 02:00:23,RD,4.7,0,351442429
(i.e. the loop would iterate twice for this single line). This means that you'd get 2019-11-08
in the first iteration and 0
in the second from this line.
The solution is not to quote the command substitution as doing so would cause the loop to iterate once over the full contents of the file which is read into $line
. The solution is not to set IFS
to a newline, as that is inelegant (it would necessitate one call to cut
in each iteration).
Instead, parse out the data that you want in a single call to cut
and read that:
while IFS= read -r datetime; do
# use "$datetime" here
done < <( cut -d, -f4 "$file" )
This uses a process substitution to create an input stream for the while
loop to read from. The data in this stream will consist of the 4th comma-delimited field in the file named by $file
.
Alternatively, with the while
loop in a subshell:
cut -d, -f4 "$file" |
while IFS= read -r datetime; do
# use "$datetime" here
done
With awk
, the processing would be cleaner (unless you need to use the date/time value as a shell variable for whatever reason):
awk -F , '{ datetime = $4; ... more code here using the datetime variable }' "$file"
Related reading:
getdatetime="$(echo" $line" | cut -f4 -d,)"
; Possible duplicate of Why does my shell script choke on whitespace or other special characters? – αғsнιη Nov 08 '19 at 11:44line='883427446627317909,1114259,1573178423,2019-11-08 02:00:23,RD,4.7,0,351442429' ; getdatetime="$(echo "$line" | cut -f4 -d,)"; echo "$getdatetime"
? – αғsнιη Nov 08 '19 at 13:45line
? – AdminBee Nov 08 '19 at 13:50$file
and all of the lines have similar construction – dcdum2018 Nov 09 '19 at 12:59for
loop. Afor
loop always iterates over a static set of words, which means you would have to let the shell read the complete file into memory only to iterate over it. This is extremely inefficient and inelegant. If you need to use a shell loop at all, you should be using awhile
loop, which reads individual lines (separately in each iteration). – Kusalananda Nov 09 '19 at 13:04$line
. i can easily get the first field but for the fourth field, only the date is fetched – dcdum2018 Nov 09 '19 at 14:18