我的输入文件()中有多行SerialNos.csv
,如下所示:
4TF16B7GA129E
4TF16B7GA129S
4TF16B7GA129D
4TF16B7GA129X
我想读取每一行,计算校验和,并将结果写入另一个文件,但我的输出文件Token.csv
只有一行输出。我该如何处理每一行?
我的代码:
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
将输出重定向放在整个循环上,而不仅仅是命令上sha256sum
。每次重定向时,您都会从头开始重新创建输出文件。这将只创建一次,并在循环内反复写入。
while IFS=$'\n' read -r line || [ -n "$line" ]
do
j=$line
serial=${j}:${epoch}:${StringToken}
echo "$serial"|sha256sum
done < "$StringCsv" > Token.csv
答案2
您正在使用以下命令循环写入文件:
echo "$serial"|sha256sum > Token.csv
但是每次循环时,您都会删除文件并写入新条目。您需要做的是每次循环时使用以下命令附加(添加到)文件:
echo "$serial"|sha256sum >> Token.csv
单引号>
告诉 bash 删除文件Token.csv
并写入内容。双引号>>
告诉 bash 将内容添加到文件末尾。
Bash 脚本现在看起来像这样:
#!/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"
有两种方法可以创建一个新的空文件,> Token.csv
如上面所用和touch Token.csv
。但是只会> Token.csv
清空现有文件。请参阅:
答案3
使用下面的命令从文件中读取 n 行:
head -n 1 filename
将其写入变量使用以下命令:
var=$(head -n 1 filename);
或者你可以从文件中读取第 n 行:
sed -n '2p' filename
上面的命令将返回文件的第二行。对于您的示例,您可以使用以下命令:sed -n $i'p' filename,其中 i 是索引。
但是,对于您的代码,您需要一个每次迭代都会增加的索引。
答案4
服用为什么使用 shell 循环来处理文本被认为是不好的做法? 方式太认真了,使用 GNU Awk 的来自协进程的 getline:
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