如何在linux bash指令碼中逐行處理檔案

在shell指令碼中逐行讀取Linux文字檔案的內容非常容易,只要處理一些微妙的問題。以下是如何以安全的方式進行。...

在shell指令碼中逐行讀取Linux文字檔案的內容非常容易,只要處理一些微妙的問題。以下是如何以安全的方式進行。

檔案、文字和習慣用法

每種程式語言都有一組習慣用法。這些都是完成一系列常見任務的標準的、不花哨的方法。它們是使用程式設計師正在使用的語言特性之一的基本方式或預設方式。它們成為程式設計師心理藍圖工具箱的一部分。

從檔案中讀取資料、處理迴圈以及交換兩個變數的值等操作都是很好的例子。程式設計師將至少知道一種方法,以一種通用的或普通的方式來實現他們的目的。也許這就足以滿足手頭的要求了。或者,他們可能會潤色程式碼,使其更有效或適用於他們正在開發的特定解決方案。但是,讓他們掌握積木習語是一個很好的起點。

瞭解和理解一種語言中的習慣用法也使學習一種新的程式語言變得更容易。瞭解一種語言是如何構造事物的,並在另一種語言中尋找等價的或最接近的事物,這是一個很好的方法,可以讓您瞭解您已經知道的程式語言和您正在學習的程式語言之間的異同。

從檔案中讀取行:一行

在Bash中,可以使用命令列上的while迴圈從檔案中讀取每一行文字並對其執行操作。我們的文字檔名為“資料.txt“它有一個一年中月份的列表。

January February March . . October November December

我們簡單的一句話是:

while read line; do echo $line; done < data.txt

如何在linux bash指令碼中逐行處理檔案

while迴圈從檔案中讀取一行,小程式的執行流傳遞到迴圈體。echo命令在終端視窗中寫入文字行。當沒有更多的行要讀取時,讀取嘗試失敗,迴圈完成。

一個巧妙的技巧是將檔案重定向到迴圈中。在其他程式語言中,您需要開啟檔案,從中讀取,然後在完成後再次關閉它。使用Bash,您可以簡單地使用檔案重定向,並讓shell為您處理所有這些低階內容。

當然,這一行不是很有用。Linux已經提供了cat命令,這正是為我們所做的。我們建立了一個冗長的方法來替換三個字母的命令。但它確實明顯地證明了從檔案中讀取的原則。

在某種程度上,這很管用。假設我們有另一個包含月份名稱的文字檔案。在此檔案中,換行符的轉義序列已附加到每一行。我們稱之為“data2.txt”

January\n February\n March\n . . October\n November\n December\n

讓我們在新檔案上用一行字。

while read line; do echo $line; done < data2.txt

如何在linux bash指令碼中逐行處理檔案

反斜槓跳脫字元“\”已被丟棄。結果是,每行都附加了一個“n”。Bash將反斜槓解釋為轉義序列的開始。通常,我們不希望Bash解釋它正在閱讀的內容。在您自己的程式碼中,讀取一行反斜槓轉義序列和所有行,並選擇解析或替換自己的程式碼更方便。

如果我們想對文字行進行任何有意義的處理或解析,我們需要使用指令碼。

用指令碼從檔案中讀取行

這是我們的劇本。它叫做“script1.sh”

#!/bin/bash Counter=0 while IFS='' read -r LinefromFile || [[ -n "${LinefromFile}" ]]; do ((Counter++)) echo "Accessing line $Counter: ${LinefromFile}" done < "$1"

我們將一個名為Counter的變數設定為零,然後定義while迴圈。

while行上的第一個語句是IFS=''。IFS代表內部欄位分隔符。它包含Bash用來標識單詞邊界的值。預設情況下,read命令去掉前導和尾隨空格。如果我們想從檔案中準確地讀取行,我們需要將IFS設定為空字串。

我們可以在迴圈外設定一次,就像設定Counter的值一樣。但是對於更復雜的指令碼,尤其是那些包含許多使用者定義函式的指令碼,IFS可能被設定為指令碼中其他地方的不同值。確保每次while迴圈迭代時IFS都被設定為空字串可以保證我們知道它的行為。

我們將把一行文字讀入一個名為LinefromFile的變數。我們使用-r(將反斜槓作為普通字元讀取)選項來忽略反斜槓。他們會像其他角色一樣被對待,不會受到任何特殊待遇。

有兩個條件將滿足while迴圈並允許迴圈體處理文字:

  • read-r LinefromFile:當從檔案中成功讀取一行文字時,read命令向while傳送一個成功訊號,while迴圈將執行流傳遞給迴圈體。請注意,read命令需要在文字行的末尾看到換行符,才能將其視為成功的讀取。如果檔案不是符合POSIX的文字檔案,則最後一行可能不包含換行符。如果read命令在換行結束前看到檔案結尾標記(EOF),它不會把它當作一個成功的閱讀。如果發生這種情況,最後一行文字將不會傳遞到迴圈體,也不會被處理。
  • [-n“${LinefromFile}”]:我們需要做一些額外的工作來處理與POSIX不相容的檔案。此比較檢查從檔案中讀取的文字。如果它不是以換行符結束的,這個比較仍然會將成功返回到while迴圈。這樣可以確保任何尾行片段都由迴圈體處理。

這兩個子句由OR邏輯運算子“| |”分隔,這樣,如果其中一個子句返回success,則無論是否有換行符,檢索到的文字都由迴圈體處理。

在迴圈體中,我們將計數器變數遞增1,並使用echo將一些輸出傳送到終端視窗。將顯示行號和每行的文字。

我們仍然可以使用重定向技巧將檔案重定向到迴圈中。在本例中,我們將重定向$1,該變數包含傳遞給指令碼的第一個命令列引數的名稱。使用這個技巧,我們可以很容易地傳入希望指令碼處理的資料檔案的名稱。

將指令碼複製並貼上到編輯器中,並用檔名“script1.sh”儲存。使用chmod命令使其可執行。

chmod +x script1.sh

如何在linux bash指令碼中逐行處理檔案

讓我們看看指令碼如何處理data2.txt文字檔案以及其中包含的反斜槓。

./script1.sh data2.txt

如何在linux bash指令碼中逐行處理檔案

行中的每個字元都逐字顯示。反斜槓不能解釋為跳脫字元。它們被印成普通字元。

將行傳遞給函式

我們還在把文字迴音到螢幕上。在現實的程式設計場景中,我們可能會對文字行做一些更有趣的事情。在大多數情況下,處理另一個函式中的行的進一步處理是一個很好的程式設計實踐。

我們可以這樣做。這是“script2.sh”

#!/bin/bash Counter=0 function process_line() { echo "Processing line $Counter: $1" } while IFS='' read -r LinefromFile || [[ -n "${LinefromFile}" ]]; do ((Counter++)) process_line "$LinefromFile" done < "$1"

我們像以前一樣定義計數器變數,然後定義一個名為process\u line()的函式。函式的定義必須出現在指令碼中首次呼叫函式之前。

我們的函式將在while迴圈的每次迭代中被傳遞給新讀取的文字行。我們可以使用$1變數在函式中訪問該值。如果有兩個變數傳遞給函式,我們就可以使用$1和$2訪問這些值,以此類推獲取更多變數。

while迴圈基本上是相同的。迴圈體內部只有一個變化。echo行已被對process\u line()函式的呼叫所替換。請注意,呼叫函式時不需要在函式名中使用“()”括號。

儲存文字行的變數LinefromFile的名稱在傳遞給函式時用引號括起來。這就迎合了有空格的線條。如果沒有引號,函式將第一個單詞視為$1,第二個單詞視為$2,依此類推。使用引號可以確保將整行文字作為$1處理。請注意,這與儲存傳遞給指令碼的相同資料檔案的$1不同。

由於計數器已在指令碼的主體中宣告,而不是在函式中,因此可以在process\line()函式中引用它。

將上述指令碼複製或鍵入到編輯器中,並使用檔名“script2.sh”儲存。使用chmod使其可執行:

chmod +x script2.sh

如何在linux bash指令碼中逐行處理檔案

現在我們可以執行它並傳入一個新的資料檔案“data3.txt”。它有一個月份列表,一行有很多單詞。

January February March . . October November \nMore text "at the end of the line" December

我們的命令是:

./script2.sh data3.txt

如何在linux bash指令碼中逐行處理檔案

這些行從檔案中讀取,並逐個傳遞給process\u line()函式。所有的行都正確顯示,包括帶有退格、引號和多個單詞的奇數行。

積木很有用

有一種思路認為習語必須包含該語言特有的東西。這不是我所認同的信仰。重要的是,它充分利用了語言,易於記憶,並提供了一種可靠而健壯的方法來實現程式碼中的某些功能。

  • 發表於 2021-04-14 18:17
  • 閱讀 ( 60 )
  • 分類:網際網路

你可能感興趣的文章

在windows中寫入批處理檔案?else語句如何工作

... 以下語法是如何在批處理檔案中使用if else語句: ...

  • 發佈於 2021-03-12 20:01
  • 閲讀 ( 53 )

使用簡單的shell指令碼修復html格式

...補補,你會喜歡shell指令碼,因為總是有調整要做。關於如何使用這些模式作為其他指令碼的基礎的一些想法包括: ...

  • 發佈於 2021-03-13 00:12
  • 閲讀 ( 48 )

什麼是shell指令碼,為什麼要使用它

... 如何執行shell指令碼?很簡單。只需將指令碼路徑作為引數傳遞給shell: ...

  • 發佈於 2021-03-13 04:53
  • 閲讀 ( 54 )

如何使用applescript將bash指令碼轉換為可單擊的應用程式

...為輸入執行它。這些特殊的應用程式被稱為水滴。下面是如何建立一個: ...

  • 發佈於 2021-03-21 09:39
  • 閲讀 ( 52 )

如何透過五個簡單步驟建立批處理(bat)檔案

... 在本文中,您將學習如何編寫一個簡單的批處理檔案。您將學習批處理檔案的基本功能以及如何自己編寫它們。我還將為您提供學習編寫批處理(BAT)檔案的更多資源。 ...

  • 發佈於 2021-03-23 08:09
  • 閲讀 ( 50 )

關於linux中bash for loops的所有知識

... 第一行告訴執行這個程式的人如何執行它(即使用bash直譯器)。第二個命令與您在命令列中輸入的任何其他命令一樣。將該檔案另存為hello_世界.sh,然後: ...

  • 發佈於 2021-03-29 06:22
  • 閲讀 ( 59 )

如何使用受限shell來限制linux使用者可以做什麼

...改其目錄,您可以控制他們可以訪問哪些命令。下面介紹如何在Linux上設定受限shell。 受限炮彈 受限shell不是另一個shell。這是標準外殼的另一種模式。Bash、Korn、Fish和其他shell都可以在受限shell模式下啟動。在本文中,我們將...

  • 發佈於 2021-03-31 10:57
  • 閲讀 ( 56 )

如何使用chsh在linux上更改預設shell

Bash不是唯一的Linux shell。很容易嘗試其他的shell,比如非常流行的Zsh。找到一個您喜歡的shell後,使用chsh命令將其設定為預設shell。我們會教你怎麼做。 為什麼貝殼很重要 shell位於您和作業系統之間。它在終端視窗內提供環境...

  • 發佈於 2021-04-02 06:04
  • 閲讀 ( 65 )

如何在linux上使用cd命令

...小又簡單。 在使用Linux計算機的第一個小時內,您將學習如何使用Bash和其他shell附帶的cd命令。也許您以前有在其他作業系統上使用它的經驗,不需要解釋。它會改變當前的工作目錄,對嗎?還有什麼要知道的? 好吧,比你想象...

  • 發佈於 2021-04-02 08:58
  • 閲讀 ( 67 )

如何在linux上使用awk命令

在Linux上,awk是一種命令列文字操作生成器,也是一種功能強大的指令碼語言。下面介紹一些最酷的功能。 awk是怎麼得名的 awk命令的名字是使用1977年編寫原始版本的三個人的縮寫:阿爾弗雷德·阿霍、彼得·溫伯格和布萊恩·...

  • 發佈於 2021-04-02 15:02
  • 閲讀 ( 49 )
我的田園貓
我的田園貓

0 篇文章

作家榜

  1. admin 0 文章
  2. 孫小欽 0 文章
  3. JVhby0 0 文章
  4. fvpvzrr 0 文章
  5. 0sus8kksc 0 文章
  6. zsfn1903 0 文章
  7. w91395898 0 文章
  8. SuperQueen123 0 文章

相關推薦