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
由於這是一個明白這一點。你使用打印命令給它一個名字,並獲得第一個文件等等我可以把它直接放入一個變量或字符串?像$ Today和$ Time等等,所以我可以用它來覆蓋bash腳本? – 2014-09-25 19:13:44
是的,但那肯定會是錯誤的做法。除非你操縱文件和流程,否則正確的做法就是用awk編寫整個腳本。發表一個新的問題來描述你的樣品輸入和預期輸出的大問題,所以我們可以幫你解決這個問題。 – 2014-09-25 19:24:10
我改變我的腳本maby你有一個建議? – 2014-09-25 20:28:55