4

There are multiple lines in my input file (SerialNos.csv), like this:

4TF16B7GA129E
4TF16B7GA129S
4TF16B7GA129D
4TF16B7GA129X

I want to read each line, compute a checksum, and write the result to another file, but my output file Token.csv only has one output line.  How can I process every line?

My Code:

epoch=$(date -d "`date`" +"%s")
StringCsv="/home/Desktop/TokenGenScript/SerialNos.csv"
StringToken=b5242a2d7973c1aca3723c834ba0d239

while IFS=$'\n' read -r line || [ -n "$line" ]
do
 j=$line
 serial=${j}:${epoch}:${StringToken}
 echo "$serial"|sha256sum > Token.csv
done < "$StringCsv"
1
  • 1
    and your code is not working or what is the problem? Btw, you don't need the doubled date.
    – pLumo
    Apr 26, 2019 at 10:41

4 Answers 4

6

Put the output redirection on the entire loop, not just the sha256sum command. Every time you redirect, you're recreating the output file from scratch. This will just create it once, and write to it repeatedly within the loop.

while IFS=$'\n' read -r line || [ -n "$line" ]
do
 j=$line
 serial=${j}:${epoch}:${StringToken}
 echo "$serial"|sha256sum
done < "$StringCsv" > Token.csv
6

You are writing to a file in a loop with this command:

echo "$serial"|sha256sum > Token.csv

However each time you loop you are erasing the file and writing a new entry. What you want to do is append (add to) the file each time you loop with this command:

echo "$serial"|sha256sum >> Token.csv

A single > tells bash to erase the file Token.csv and write the contents. A double >> tells bash to add to the end of the file.


The bash script would now look like this:

#!/bin/bash
epoch=$(date -d "`date`" +"%s")
StringCsv="/home/Desktop/TokenGenScript/SerialNos.csv"
StringToken=b5242a2d7973c1aca3723c834ba0d239

> Token.csv # Empty file from last run

while IFS=$'\n' read -r line || [ -n "$line" ]
do
 j=$line
 serial=${j}:${epoch}:${StringToken}
 echo "$serial"|sha256sum >> Token.csv # Append new record to end
done < "$StringCsv"

There are two ways to create a new empty file > Token.csv as used above and touch Token.csv. However only > Token.csv will empty an existing file. See:

5
  • There should probably be an explicit removal/truncation of Token.csv prior to the loop, to assure this run doesn't append to any existing file contents. Apr 26, 2019 at 14:40
  • As you explained in your answer to the question you linked to,  touch does not empty a file. Apr 27, 2019 at 16:56
  • @Scott Yes that was misleading. I've reworded it. Thanks for pointing that out. Apr 27, 2019 at 17:24
  • @MontyHarder I've added a full script now. Apr 27, 2019 at 17:26
  • @Scott Double thanks. OP never had a shebang in the first place which I was planning to mention in the answer as well. The whole second edit was rather rushed as I had a priority project under way. Apr 27, 2019 at 17:55
0

Use the command below for reading n lines from file:

head -n 1 filename

to write it to variable use this:

var=$(head -n 1 filename);

Or you can read nth line from file:

sed -n '2p' filename

The comand above will return second line of file. For your example you can use this: sed -n $i'p' filename where i is index.

BUT, for your code you need an index that will increase every iteration.

0

Taking Why is using a shell loop to process text considered bad practice? way too seriously, and using GNU Awk's getline from a Coprocess:

gawk -v stringToken=b5242a2d7973c1aca3723c834ba0d239 '
  BEGIN{cmd="sha256sum"; s = systime()} 
  {
    print $0 s stringToken |& cmd; close(cmd,"to"); 
    cmd |& getline; close(cmd,"from")
  } 1
' SerialNos.csv > Token.csv

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .