如何在Linux中讀取檔案中特定的一行?
在使用Linux shell時,讀取文字檔案通常是一個重要的操作。有時,我們可能只對讀取檔案中的特定一行感興趣。
我們將看看從檔案中獲取特定文字的不同方法。
實際問題
讓我們來看一個例子。
假設我們有一個名為“test.txt”的檔案:
$ nl test.txt 1 This is line 1, I don't have any interesting data. 2 This is line 2, I don't have any interesting data. 3 This is line 3, I don't have any interesting data. 4 This is line 4, I don't have any interesting data. 5 This is line 5, interesting data: Linux is awesome! 6 This is line 6, I don't have any interesting data. 7 This is line 7, I don't have any interesting data.
我們使用nl函式顯示帶有行號的文字檔案內容。
我們知道前四行包含一些有趣的資訊。因此,我們只想讀取第五行。
在Linux命令列中有很多方法可以做到這一點。在本指南中,我們將介紹四種不同的方法:
使用Bash命令
使用sed命令
使用awk命令
使用head和tail命令
讓我們來看一些例子。
使用Bash命令
為了解決這個問題,我們需要編寫一個名為getLine的shell指令碼。
$ cat getLine.sh #!/bin/bash FILE="$1" LINE_NO=$2 i=0 while read line; do i=$(( i + 1 ) test $i = $LINE_NO && echo "$line"; done <"$FILE"
上面的shell指令碼接受兩個引數:檔名和目標行號。
基本上,它包含一個段落。我們首先將$i的值設定為零。然後我們檢查當前行是否與我們目標的行(第十行)匹配。如果是,我們將$i加1。否則,我們將列印當前行。
命令
$ ./getLine.sh test.txt 5
輸出
This is line 5, interesting data: Linux is awesome!
結果顯示我們的指令碼執行成功。
如果我們仔細閱讀文字,我們可能會改進它。
我們在迴圈中檢查字串中的每一個字元,即使我們已經找到並列印了我們想要的字元。實際上,我們可能在找到我們想要的內容之前處理了大量資料。但是,讓我們堅持這個例子!我們的示例輸入只有七行。然而在現實世界中,您的輸入可能包含數百萬行。
因此,如果我們能夠在找到正確的行後退出迴圈,那就太好了。所以,讓我們稍微修改一下指令碼:
$ cat getLine2.sh #!/bin/bash FILE="$1" LINE_NO=$2 i=0 while read line; do i=$(( i + 1 )) case $i in $LINE_NO) echo "$line"; break;; esac done <"$FILE"
我們使用case語句在找到我們想要的行時停止迴圈。讓我們看看它是否有效:
命令
$ ./getLine2.sh test.txt 5
輸出
This is line 5, interesting data: Linux is awesome!
我們透過使用一些bash指令碼解決了這個問題。
使用sed命令
sed命令非常擅長解決這類問題。這裡有兩個簡潔的sed單行命令可以完成這項工作。
命令
$ sed '5!d' test.txt
輸出
This is line 5, interesting data: Linux is awesome!
命令
$ sed -n '5p' test.txt
輸出
This is line 5, interesting data: Linux is awesome!
要刪除目錄中除第五行(也是唯一一行)以外的所有行,請使用以下命令:5!d 要只顯示第五行(也是唯一一行),請使用以下命令:-n '5p'
這兩個單行指令碼按預期執行。但是,它們會逐行讀取整個輸入,這對於大型檔案來說花費的時間太長。
shell指令碼提供了一個“q”(退出)選項來退出進一步的執行。因此,我們可以使用“&&”運算子將這兩個命令組合成一行:
命令
$ sed '5!d;q' test.txt
輸出
This is line 5, interesting data: Linux is awesome!
命令
$ sed -n '5{p;q}' test.txt
輸出
This is line 5, interesting data: Linux is awesome!
我們沒有注意到兩個輸出之間的任何差異,因此讓我們使用sed -e's/^.*$//'命令刪除從每一行開頭到行尾的所有內容。
讓我們首先快速瀏覽一下沒有“q”命令的版本。
命令
$ sedsed -d '5!d' test.txt
輸出
PATT:This is line 1, I don't have any interesting data.$ HOLD:$ COMM:5 !d PATT:This is line 2, I don't have any interesting data.$ ... This is line 5, interesting data: Linux is awesome! PATT:This is line 6, I don't have any interesting data.$ HOLD:$ COMM:5 !d PATT:This is line 7, I don't have any interesting data.$ HOLD:$ COMM:5 !d
然後我們可以看到sed命令已經從第一個字元處理到最後一個字元(第七個字元)。
我們現在將使用q測試sed命令。
命令
$ sedsed -d '5!d;q' test.txt
輸出
PATT:This is line 1, I don't have any interesting data.$ HOLD:$ COMM:5 !d PATT:This is line 2, I don't have any interesting data.$ ... PATT:This is line 5, interesting data: Linux is awesome!$ HOLD:$ COMM:q This is line 5, interesting data: Linux is awesome!
除錯輸出表明sed處理在第5行停止。
使用awk命令
另一個強大的文字處理工具是awk。您可以使用它用一行程式碼來解決問題:awk 'NR == 5' input.txt。
我們不想在列印第5行後繼續處理。
類似地,awk也有“quit”命令來退出當前處理。
命令
$ awk 'NR==5{ print; exit }' test.txt
輸出
This is line 5, interesting data: Linux is awesome!
因此,如輸出所示,我們已經解決了這個問題。
使用head和tail命令
我們可以使用`tail`命令提取文字文件的最後部分。
我們還可以使用這兩個命令的組合來讀取特定行。
讓我們假設我們要讀取x行。思路是:
我們首先使用head命令從輸入檔案中獲取第1行到第X行。
然後我們將第一步的輸出透過管道傳遞到tail命令以檢索最後一個條目:head -n X input | tail -1
讓我們看看這個想法對我們的例子是否有效:
命令
$ head -n 5 test.txt | tail -1
輸出
I am line 5, interesting data: Linux is awesome!
我們得到了預期的結果,並且我們解決了這個問題。
結論
我們討論了在Linux中從輸入檔案讀取單行的不同方法。
我們討論瞭如何提高bash、awk和/或sed解決方案的效能。
資料結構
網路
關係資料庫管理系統(RDBMS)
作業系統
Java
iOS
HTML
CSS
Android
Python
C語言程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP