2014-09-24 54 views
0

我是新來的,也是編程的入門者,所以請小心處理。用awk在bash腳本和商店中從文件中提取數據

Filename = Datafile.tmp 

我得到一個日誌文件與1號線這樣的數據(逗號分隔)

24092014,17:21,357.7,5.1,49.96,228.6,7.9,1757.5,3378200.0,28.2,20680.0,846.0,1800.0,2  

莫比我必須解釋shomething。我在BASH寫了一個腳本,通過內部例程讀取變頻器的數據。我想更改該腳本,以便像上面那樣從數據文件中讀取數據。劇本很長,但只是閱讀部分的地方。 所以我想我可以刪除所有的閱讀端口例程,只是專注於

將數組中的數據轉換爲我的情況下從文件中讀取數據。 並在bottum存儲變量到工作文件

#Ask data from inverter 
get_data() { 
printf $GetDataCMD > $PORT 
dd if=$PORT of=$OUT bs=1 count=$dataLengthTotal & 
PID=$! 
sleep 3 
if [ -d /proc/$PID ] 
then 
    rcvd="no" 
    kill $PID 
else 
    rcvd="yes" 
fi 
} 

#Put received data in array and check for errors 
receive_data() { 
((dataLengthTotal = $ANS_OFFSET+$dataLengthOutput+1)) 
retry_counter=$RETRY 
while ((retry_counter)); do 
get_data < $PORT 2>/dev/null 
if [ $rcvd = "yes" ]; then 

    data=(`od -b -v $OUT | sed -e 's/^[0-9]*//g' | sed -e 's/[ ]\([0-9]\)/ 0\1/g'`) 

    if [ ${#data[@]} -ne $dataLengthTotal ]; then 
    rcvd="nochk" 
    echo -e `date -R`": Wrong amount of data received\r" >> $LOG 
    init_comport 
    ((retry_counter -= 1)) 
    else 
    # Check CRC 
    sumstr="${data[@]:$ANS_OFFSET:$dataLengthOutput}" 
    let sum=${sumstr// /+} 
    if ((sum%256 == data[9+$dataLengthOutput])); then 
     rcvd="chk" 
     retry_counter=0 
    else 
     rcvd="nochk" 
     echo -e `date -R`": Checksum error in received data\r" >> $LOG 
     init_comport 
     ((retry_counter -= 1)) 
    fi 
    fi 
else 
    init_comport 
    ((retry_counter -= 1)) 
fi 
done 
} 

#convert data from array into readable data 
get_current_data() { 
dataLengthOutput=30 
GetDataCMD=$GetCurrentDataCMD 
receive_data 
if [ $rcvd = "chk" ]; then 
#errorbits 
((errbits = data[9+7] * 256 + data[9+6])) 
#Voltage Solarpanels (Usol) 
((Usol = data[9+9] * 256 + data[9+8])) 
#Current Solarpanels (Isol) 
((Isol = data[9+11] * 256 + data[9+10])) 
#AC Frequency (Fnet) 
((Fnet = data[9+13] * 256 + data[9+12])) 
#AC Voltage (Unet) 
((Unet = data[9+15] * 256 + data[9+14])) 
#AC Current (Inet) 
((Inet = data[9+17] * 256 + data[9+16])) 
#AC Power (Pnet) 
((Pnet = data[9+19] * 256 + data[9+18])) 
#Total delivered (Etot) 
((Etot = data[9+22] * 65536 + data[9+21] * 256 + data[9+20] + WtotOffset)) 
#Temp Inverter (Tinv) 
((Tinv = data[9+23])) 
#Total runtime (Htot) 
((Htot = data[9+26] * 65536 + data[9+25] * 256 + data[9+24] + HtotOffset)) 
#Total CO2 (Ctot) 
((Ctot = Etot * $CO2perc/100)) 
fi 
} 

#check, convert and write error messages 
convert_errorbits() { 
ErrorStr="Systeem_OK" 
if ((errbits)); then 
if ((errbits & 0x01)); then 
    ErrorStr="Usolar too high (`print_float $Usol 1` V). ${ErrorStr}" 
fi 
if ((errbits & 0x02)); then 
    ErrorStr="Usolar too low (`print_float $Usol 1` V). ${ErrorStr}" 
fi 
if ((errbits & 0x04)); then 
    ErrorStr="No mains detected. ${ErrorStr}" 
fi 
if ((errbits & 0x08)); then 
    ErrorStr="Uac too high (${Unet} V). ${ErrorStr}" 
fi 
if ((errbits & 0x10)); then 
    ErrorStr="Uac too low (${Unet} V). ${ErrorStr}" 
fi 
if ((errbits & 0x20)); then 
    ErrorStr="FreqAC too high (`print_float $Fnet 2` Hz). ${ErrorStr}" 
fi 
if ((errbits & 0x40)); then 
    ErrorStr="FreqAC too low (`print_float $Fnet 2` Hz). ${ErrorStr}" 
fi 
if ((errbits & 0x80)); then 
    ErrorStr="Temperature error (${Tinv}ºC). ${ErrorStr}" 
fi 
if ((errbits & 0x100)); then 
    ErrorStr="Hardware error. ${ErrorStr}" 
fi 
if ((errbits & 0x200)); then 
    ErrorStr="Starting. ${ErrorStr}" 
fi 
if ((errbits & 0x400)); then 
    ErrorStr="Max output (${Pnet} W). ${ErrorStr}" 
fi 
if ((errbits & 0x800)); then 
    ErrorStr="I max (`print_float $Isol 2` A). ${ErrorStr}" 
fi 
echo -e `date -R`": Error message: $ErrorStr\r" >> $LOG 
fi 
} 

#Get current day output 
get_current_day() { 
dataLengthOutput=8 
((daynr = 0)) 
((crc = $GetDailyDataCRC+$daynr)) 
GetDataCMD=$GetDailyDataCMD1\\x`printf "%02X" $1 $daynr`$GetDailyDataCMD2\\x`printf "%02X" $1 $crc` 
receive_data 
if [ $rcvd = "chk" ]; then 
# Profit [kWH] 
((Etoday = data[9+7] * 256 + data[9+6])) 
# Runtime [h:mm] 
((Htoday = data[9+5] * 5)) 
# CO2 
((CO2 = Etoday * $CO2perc/100)) 
fi 
} 



# Main Program 
main(){ 
#set time variables 
MTIME=`date +%M` 
HTIME=`date +%H` 

# Configure serial port 
init_comport 

#Store file contains data needed for calculating totals etc 
#Internally an array is used, values are: 
#0=Active flag 
#1=WtotAct 
#2=HtotAct 
#3=WtotLog 
#4=HtotLog 
#fill array 
store=(`cat $STORE`) 

get_current_data 

if [ $rcvd = "chk" ]; then 
if ((! store[0])); then 
    echo -e `date -R`": Waking up; Inverter started.\r" >> $LOG 
    store[0]=1 
    if ((USE_30DAYS)); then 
    get_last_30_days 
    fi 
    if [ ! -f $PVDIARYCSV ] 
    then 
    create_pvdiary 
    fi 
    if ((USE_EMAIL)) && ((USE_EMAwake)); then 
    email_send "Bericht van uw zonnepanelen : ontwaken." "I'm awake now !\n\nUw Mastervolt Omvormer\n" 
    fi 
fi 

# Remember 'old-values' for calculating PVDiary inputs 
((store[5] = store[1])) 
((store[6] = 0)) 

# Put total values into array for calculating daily profit 
store[1]=$Etot 
store[2]=$Htot 

convert_errorbits 
get_current_day 
create_actual_page 
rrd_update 
fill_pvdiary 
fill_sql 
pvoutput_live_update 
fi 

#Write message before sleep 
if [ $rcvd = "no" ] && ((! retry_counter)) && ((store[0])); then 
echo -e `date -R`": No reaction from Inverter; entering sleep\r" >> $LOG 
create_offline_page 
store[0]=0 
fi 

#Write 0-values in PVDiary-file 
if [ $rcvd = "no" ] && ((! retry_counter)) ; then 
((store[5] = store[1])) 
((store[6] = 0)) 
fill_pvdiary 
((store[5] = store[1])) 
((store[6] = 0)) 
fill_sql  
((store[5] = 0)) 
fi 

#Run timebased scripts (internal cron) 
if [ $HTIME = 23 ] && [ $MTIME = 00 ]; then 
fill_csv 
fi 
if [ $MTIME = 00 ] && ((USE_RRD)); then 
graph 
fi 
if [ $MTIME = 00 ] && ((store[0])) && ((USE_EMAIL)) && ((USE_EMAhour)); then 
email_send_actual "Bericht van uw zonnepanelen : productie tot nu toe." 
fi 

#storing variables to working file 
echo ${store[0]} ${store[1]} ${store[2]} ${store[3]} ${store[4]} ${store[5]}${store[6]}> $STORE 
} 

#What to do ? 
case $1 in 
"help" ) help;; 
"create") create;; 
"draw" ) graph;; 
*  ) main;; 
esac 

回答

1
$ awk -F, '{print "Today = " $1 "\nTime = " $2 "\nHertz = " $5}' file 
Today = 24092014 
Time = 17:21 
Hertz = 49.96 
+0

由於這是一個明白這一點。你使用打印命令給它一個名字,並獲得第一個文件等等我可以把它直接放入一個變量或字符串?像$ Today和$ Time等等,所以我可以用它來覆蓋bash腳本? – 2014-09-25 19:13:44

+0

是的,但那肯定會是錯誤的做法。除非你操縱文件和流程,否則正確的做法就是用awk編寫整個腳本。發表一個新的問題來描述你的樣品輸入和預期輸出的大問題,所以我們可以幫你解決這個問題。 – 2014-09-25 19:24:10

+0

我改變我的腳本maby你有一個建議? – 2014-09-25 20:28:55