成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Shell逐行處理文本求和,我人傻了...

開發 前端
我們預期的應該是遇到換行才停止讀取,為了達到這個目的,我們可以設置這個標記,即通過設置IFS來達到目的。

[[404180]]

本文轉載自微信公眾號「編程珠璣」,作者守望先生 。轉載本文請聯系編程珠璣公眾號。

假設要要計算文本test.data的第二列的數字之和:

  1. 1 12  
  2. 2 23  
  3. 3 34  
  4. 4 56  

當然你可能會這樣處理:

  1. awk '{s+=$2} END {print s}' test.data  

很快就得到了結果。不過,本文要說的點與awk無關。我們通過另外一種方式來計算,即逐行分析處理的方式。

嘗試一

我們嘗試第一種方式,shell實現如下:

  1. #!/usr/bin/env bash 
  2. sum=0 
  3. cat test.data | while read line 
  4. do 
  5.     temp_num=$(echo "$line" | cut -d ' ' -f 2) 
  6.     sum=$(( $sum + $temp_num )) 
  7. done 
  8. echo "we get sum:$sum" 

輸出結果:

  1. we get sum:0 

這是為什么!為什么得到的結果會是0呢?

這事壞就壞在腳本中的|,眾所周知,這是一個管道命令,而這也就意味著,while循環的執行結果都是在一個subshell中,一旦這個subsell退出了,它里面的結果也就沒有了。

其實這個問題利用有了這個神器,再也不怕shell寫得不對了中提到的工具很容易發現:

  1. $ shellcheck myscript 
  2.  
  3. Line 3: 
  4. cat test.data | while read line 
  5.     ^-- SC2002: Useless cat. Consider 'cmd < file | ..' or 'cmd file | ..' instead. 
  6.                       ^-- SC2162: read without -r will mangle backslashes. 
  7.  
  8. Line 6: 
  9.     sum=$(( $sum + $temp_num )) 
  10.     ^-- SC2030: Modification of sum is local (to subshell caused by pipeline). 
  11.             ^-- SC2004: $/${} is unnecessary on arithmetic variables. 
  12.                    ^-- SC2004: $/${} is unnecessary on arithmetic variables. 
  13.  
  14. Line 8: 
  15. echo "we get sum:$sum" 
  16.                  ^-- SC2031: sum was modified in a subshell. That change might be lost. 
  17.  

嘗試二

既然管道命令不建議用,那么我們使用下面的方式看看:

  1. #!/usr/bin/env bash 
  2. sum=0 
  3. for line in $(cat test.data) 
  4. do 
  5.     echo "get line :$line" 
  6.     temp_num=$(echo "$line" | cut -d ' ' -f 2) 
  7.     sum=$(( $sum + $temp_num )) 
  8. done 
  9. echo "we get sum:$sum" 

輸出結果:

  1. get line :1 
  2. get line :12 
  3. get line :2 
  4. get line :23 
  5. get line :3 
  6. get line :34 
  7. get line :4 
  8. get line :56 
  9. we get sum:135 

從結果中看出,如果文本中存在空格或者tab等,則看似每次讀取一行,實際上是遇到空格,tab或換行就停止讀取了,并沒有達到我們的目的。

我們預期的應該是遇到換行才停止讀取,為了達到這個目的,我們可以設置這個標記,即通過設置IFS來達到目的。在上面的shell開頭加上:

  1. IFS=$'\n' 

但是修改為這樣之后,在自己的系統上并沒有得到我想要的效果,有知道的讀者可以告知一下。

嘗試三

讓我們再換一種方式:

  1. #!/usr/bin/env bash 
  2. sum=0 
  3. while read line 
  4. do 
  5.     echo "line $line" 
  6.     temp_num=$(echo "$line" | cut -d ' ' -f 2) 
  7.     sum=$(( $sum + $temp_num )) 
  8. done < "test.data" 
  9. echo "we get sum:$sum" 

這種方式我們是能得到正確結果的。

當然,如果你要讀取指定列,你還可以像下面這樣做:

  1. #!/usr/bin/env bash 
  2. sum=0 
  3. while read col1 col2 
  4. do 
  5.     sum=$(( $sum + $col2 )) 
  6. done < "test.data" 
  7. echo "we get sum:$sum" 

其中col1,col2就分別代表了第一列,第二列,使用的時候,可以直接使用對應列的內容。

但是,如果我們要讀取的內容包括了轉義字符會怎么辦?例如:

  1. \n 12 
  2. \n 23 
  3. \n 34 
  4. \n 56 

執行結果:

  1. line  
  2.  12 
  3. line  
  4.  23 
  5. line  
  6.  34 
  7. line  
  8.  56 
  9. we get sum:125 

從結果可以看到,雖然內容能否讀取到,但是內容被打印出來的時候,已經變了,\被當成轉義字符處理了,如果不想讓它轉義處理怎么辦?只需要加上-r參數即可:

  1. while read -r line 

總結

在逐行處理文本過程中,主要關注以下幾種情況:

  • 行中有空格,tab
  • 行中有轉義字符

另外,通過shellcheck工具也會發現,它并不推薦for in file這種方式逐行處理文本:

  1. Line 3: 
  2. for line in $(cat test.data) 
  3.             ^-- SC2013: To read lines rather than words, pipe/redirect to a 'while read' loop. 

作者:守望,linux應用開發者,目前在公眾號【編程珠璣】,分享Linux/C/C++/數據結構與算法/工具等原創技術文章和學習資源

原文鏈接:https://mp.weixin.qq.com/s/rW0Va8g0U3apxNwR0Ziw9w

 

責任編輯:武曉燕 來源: 編程珠璣
相關推薦

2021-06-09 07:15:20

Shell逐行處理

2021-06-22 09:32:40

Linuxshell命令

2021-08-20 10:46:25

Shell腳本文件Linux

2021-04-21 08:03:34

腳本Shell讀取

2017-03-02 18:10:20

LinuxShell命令

2016-03-30 11:16:33

2024-09-12 17:39:27

2021-09-10 16:30:29

LinuxShell文本

2024-01-07 16:46:19

FiberHTTPWeb

2019-10-14 11:31:51

工具代碼開發

2024-08-12 09:43:42

2013-07-16 16:37:12

91百度

2020-11-21 19:04:33

技術開發指標

2013-08-30 10:25:22

Shell主機監控

2025-06-25 07:08:09

grepsedawk

2020-12-23 11:08:10

Python代碼文本

2021-03-28 08:57:57

Python 文本數據

2018-12-28 10:45:08

Linux文本行命令

2011-04-14 14:37:06

職場

2013-06-03 11:28:05

shell命令
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: a在线观看 | 日日操网站 | 精品一区二区在线观看 | 91精品久久久久久久久久小网站 | 天堂av在线影院 | 男女啪啪网址 | 日本黄色一级视频 | 国产在线激情视频 | 日韩av一区二区在线观看 | 精品日韩在线 | 国产精品一区网站 | 国产精品日日做人人爱 | 久草在线高清 | 在线免费观看黄色 | 久久精品免费一区二区三 | 希岛爱理在线 | 欧美精品v国产精品v日韩精品 | 欧美日韩电影一区二区 | 成人精品视频在线观看 | 亚洲精品视频二区 | 成人伊人| 国产成人99久久亚洲综合精品 | 久久免费国产视频 | 毛片网站在线观看 | 精品欧美一区二区三区精品久久 | 久久国产一区二区三区 | 午夜视频在线免费观看 | 国产精品毛片 | 97起碰| 精品一区二区电影 | 亚洲精品无人区 | 国产在线精品一区二区三区 | 亚洲精品乱码久久久久久蜜桃 | 欧美日韩久久久久 | 国产激情91久久精品导航 | 久久极品 | 在线视频亚洲 | 国产精品免费看 | 欧美五月婷婷 | 视频在线亚洲 | 精品国产1区2区3区 一区二区手机在线 |