1. 程式人生 > >Linux--Shell指令碼逐行讀文字處理並curl傳送post請求json格式等問題

Linux--Shell指令碼逐行讀文字處理並curl傳送post請求json格式等問題

問題:Shell指令碼逐行讀取文字,字串分割,Curl傳送Post請求Json格式等相關問題

在linux中使用curl傳送一個post請求時,帶有json的資料,在傳送時發現json中的變數沒有解析出來:

curl -d '{"Pin": "${line}"}' -H"tp-app-id:publicclouds" -H"tp-sig:e26fe2c1924d9b4d86d19145434e3a5e" -H"tp-ts:14x6204133" -H"Content-Type:application/json" http://localhost:8070/alarm/activityPush

錯誤提示:

{"Code":1, "Msg":"invalid character '$' looking for beginning of value"}

這與json傳資料的單引號 ('') 有關,shell指令碼中('')內的字串都只能原樣輸出。

解決方案,在資料上再加上單引號('') :

curl -d '{"Pin": "'${line}'"}' -H"tp-app-id:publicclouds" -H"tp-sig:e26fe2c1924d9b4d86d19145434e3a5e" -H"tp-ts:14x6204133" -H"Content-Type:application/json" http://localhost:8070/alarm/activityPush

相關栗子:

逐行讀取文字文件中的資料,拆分存入陣列,傳入json進行curl請求:

#!/bin/bash
echo "output" > 2.txt
cat test.txt | while read line
do
        echo "File:${line}"
        echo ${line} >> 2.txt

        #array=(${line//,/ })    #replace , to " "
        #for var in ${array[@]}
        #do
        #       echo $var >>2.txt
        #done

        old_ifs="$IFS"
        IFS=","
        array=($line)
        IFS="$old_ifs"
        i=0
        while [ $i -lt ${#array[@]} ]
        do
                echo ${array[i]}
                let i++
        done

        curl -d '{"Pin": "'${line}'"}' -H"tp-app-id:publiccloud" -H"tp-sig:e26fe2c1924d9b4d86d19145434e3a1e" -H"tp-ts:1456204133" -H"Content-Type:application/json" http://localhost:8070/alarm/activityPush >> 2.txt
done

讀取文件

提示錯誤資訊:

invalid character '\r' in string literal"

由於在shell處理了windows裡的字元檔案,導致本該輸出成兩行的字串變成了一行,而第一行行首的一些字元被第二行覆蓋了

這是由於windows和linux下的/r ^M 字元的區別導致,可以將異常字元都篩選掉再進行輸出:如sed 's/[^0-9,.:A-Za-z]//g'把不符合規則的字元過濾掉

Unix體系裡,每行結尾只有“<換行>”,即“\n”;Windows體系裡面,每行結尾是“<換行><回 車>”,即“\n\r”。一個直接結果是,Unix體系下的檔案在Windows裡開啟的話,所有文字會變成一行;而Windows裡的檔案在Unix下開啟的話,在每行的結尾可能會多出一個^M符號。

好了,所以我的題目就出在被處理懲罰的檔案的每行末尾都有^M符號,而這凡是是看不出來的。可以用"cat -A test.file"號令檢視。是以當我想在行尾新增字元的時辰,它老是新增在行首且會覆蓋掉本來行首的字元。

要把檔案轉換一下,有兩種辦法:

  1. 命令列:dos2unix test.file
  2. 去掉"\r" ,用號令sed -i ""s/\r//"" test.file

shell指令碼逐行讀取

經常會對文體檔案進行逐行處理,在Shell裡面如何獲取每行資料,然後處理該行資料,最後讀取下一行資料,迴圈處理.有多種解決方法如下:

1.通過read命令完成.

read命令接收標準輸入,或其他檔案描述符的輸入,得到輸入後,read命令將資料放入一個標準變數中.

利用read讀取檔案時,每次呼叫read命令都會讀取檔案中的"一行"文字.

當檔案沒有可讀的行時,read命令將以非零狀態退出.

cat data.dat | while read line
do
    echo "File:${line}"
done

while read line
do 
    echo "File:${line}"
done < data.dat

2.使用for var in file 命令完成

for var in file 表示變數var在file中迴圈取值.取值的分隔符由$IFS確定.

for line in $(cat data.dat)
do 
    echo "File:${line}"
done

for line in `cat data.dat`
do 
    echo "File:${line}"
done

如果輸入文字每行中沒有空格,則line在輸入文字中按換行符分隔符迴圈取值.

如果輸入文字中包括空格或製表符,則不是換行讀取,line在輸入文字中按空格分隔符或製表符或換行符特環取值.可以通過把IFS設定為換行符來達到逐行讀取的功能.

IFS的預設值為:空白(包括:空格,製表符,換行符).

3.使用awk命令完成

awk是一種優良的文字處理工具,提供了極其強大的功能.

利用awk讀取檔案中的每行資料,並且可以對每行資料做一些處理,還可以單獨處理每行資料裡的每列資料.

cat data.dat | awk '{print $0}'
cat data.dat | awk 'for(i=2;i<NF;i++) {printf $i} printf "\n"}'

第1行程式碼輸出data.dat裡的每行資料,第2程式碼輸出每行中從第2列之後的資料.

如果是單純的資料或文字檔案的按行讀取和顯示的話,使用awk命令比較方便.

分割字串

  1. shell變數的字串替換直接分割
  2. 自定義IFS變數, 改變分隔符, 對字串進行切分

1.用string來替換parameter變數中所有匹配的pattern

${parameter//pattern/string} 
#array=(${line//,/ })    #replace , to " "
#for var in ${array[@]}
#do
#       echo $var >>2.txt
#done

2.當 shell 處理"命令替換"和"引數替換"時,shell 根據 IFS 的值,預設是 space, tab, newline 來拆解讀入的變數,然後對特殊字元進行處理,最後重新組合賦值給該變數。

檢視變數 IFS 的值:

    $ echo $IFS  
      
    $ echo "$IFS" | od -b  
    0000000 040 011 012 012  
    0000004  

直接輸出IFS是看不到的,把它轉化為二進位制就可以看到了,"040"是空格,"011"是Tab,"012"是換行符"\n" 。最後一個 012 是因為 echo 預設是會換行的。

old_ifs="$IFS"
IFS=","
array=($line)
IFS="$old_ifs"
i=0
while [ $i -lt ${#array[@]} ]
do
    echo ${array[i]}
    let i++
done

End