我有一个包含以下内容的文件;
864440 17:59:48.143
864440 17:59:48.221
864441 17:59:48.159
864441 17:59:48.221
864442 17:59:48.159
864442 17:59:48.237
864443 17:59:48.174
864444 17:59:48.190
864444 17:59:48.253
864445 17:59:48.206
864445 17:59:48.268
864446 17:59:48.221
864446 17:59:48.284
我正在做一个while循环来读取第一个和第二个值并将它放在如下的变量上;
while read list; do
jbnum=`echo $list|awk '{print $1}'`
time=`echo $list|awk '{print $2}'`
done < jobstmp.txt
我想添加一个if条件,如果jbnum等于下一次迭代,它将获得相同作业编号的时间差,如果没有那么什么都不做并转到下一次迭代
感谢所有根据Chris Maes提供的代码回答以下解决方案的人
while read jobnum time
do
if [[ "$prevjobnum" == "$jobnum" ]]
then
ENDTIME=`date +%s.%N -d "$time"`
STARTTIME=`date +%s.%N -d "$prevtime"`
DIFF=$(echo $ENDTIME - $STARTTIME | bc | sed 's/0\{1,\}$//')
echo "$prevjobnum time is $DIFF seconds"
fi
# keep variables for next iteration
prevjobnum=$jobnum
prevtime=$time
done < jobstmp.txt
答案 0 :(得分:1)
你无法提前阅读。你将不得不使用一些中间变量;类似的东西(注意你可以立即读取多个变量):
while read jobnum time
do
if [[ "$prevjobnum" == "$jobnum" ]]
then
#do your stuff with the variables $prevjobnum and $prevtime. for example:
echo "prevjobnum=$prevjobnum , prevtime=$prevtime"
fi
# keep variables for next iteration
prevjobnum=$jobnum
prevtime=$time
done < jobstmp.txt
这给出了:
prevjobnum=864440 , prevtime=17:59:48.143
prevjobnum=864441 , prevtime=17:59:48.159
prevjobnum=864442 , prevtime=17:59:48.159
prevjobnum=864444 , prevtime=17:59:48.190
prevjobnum=864445 , prevtime=17:59:48.206
prevjobnum=864446 , prevtime=17:59:48.221
答案 1 :(得分:0)
请注意,您的方法可以通过不必解析$list
的方式进行改进。使用read var1 var2 var3...
按照Read a file line by line assigning the value to a variable:
这样,你可以得到这样的代码:
while IFS= read -r jbnum time; do
if [ "$prev_jbnum" == "$jbnum" ]; then
echo "they are equal!"
fi
prev_jbnum=$jbnum
done < jobstmp.txt
但是,要将一列与前一列进行比较,您可以更简单的方式使用awk
:
$ awk '$1==prev {print $0, "equal!"} {prev=$1}' file
864440 17:59:48.221 equal!
864441 17:59:48.221 equal!
864442 17:59:48.237 equal!
864444 17:59:48.253 equal!
864445 17:59:48.268 equal!
864446 17:59:48.284 equal!
要比较第一个字段匹配的时间,您可以使用mktime()
之类的内容,只是它不会处理毫秒。
此外,您必须对数据进行一些按摩才能使用此功能:
{
gsub(/[^0-9]/, " ", $2) # replace every : and . with spaces
current_time=mktime("1970 01 01 " $2); # generate a date prepending 1/1/1970
}
答案 2 :(得分:0)
如果您的ID总是6个字符宽,则可以使用uniq
过滤具有特定第一个字段值的第一行:
$ echo """864440 17:59:48.143
864440 17:59:48.221
864441 17:59:48.159
864441 17:59:48.221
864442 17:59:48.159
864442 17:59:48.237
864443 17:59:48.174
864444 17:59:48.190
864444 17:59:48.253
864445 17:59:48.206
864445 17:59:48.268
864446 17:59:48.221
864446 17:59:48.284""" | uniq -w 6
864440 17:59:48.143
864441 17:59:48.159
864442 17:59:48.159
864443 17:59:48.174
864444 17:59:48.190
864445 17:59:48.206
864446 17:59:48.221
然后,您可以在输出行上进行迭代,以便只应该通过第一个字段值执行一次操作。
请注意,必须对数据进行排序才能使uniq
正常工作。
答案 3 :(得分:0)
我建议你在循环之前先做一次阅读
read line
while read nextLine; do
jbnum=`echo $line|awk '{print $1}'`
time=`echo $line|awk '{print $2}'`
nextjbnum=`echo $nextLine|awk '{print $1}'`
nexttime=`echo $nextLine|awk '{print $2}'`
if [jbnum == nextjbum]; then
DO STUFF ....
fi
#Then save the current line before processing the next
line=nextLine
done
答案 4 :(得分:0)
在包含
的{}内执行计算打印$ 1,“//在此处进行计算”
awk 'idMap[$1]==""{idMap[$1]=$2;print;next;}{print $1,"//do your calculation here"}' <filaname>
此时生成的输出看起来像这样。
864440 17:59:48.143
864440 //do your calculation here
864441 17:59:48.159
864441 //do your calculation here
864442 17:59:48.159
864442 //do your calculation here
864443 17:59:48.174
864444 17:59:48.190
864444 //do your calculation here
864445 17:59:48.206
864445 //do your calculation here
864446 17:59:48.221
864446 //do your calculation here