跳轉到內容

Unix/命令/文字處理指南

來自華夏公益教科書

Unix 支援多種文字處理命令。

awk 是一個強大的文字處理工具,使用正則表示式,提供了超出 #cut#sed 的擴充套件功能。您可以在 AWKAWK 入門 華夏公益教科書中瞭解更多資訊。

單行示例

  • echo abcd |awk '/b.*d/'
    • 輸出與正則表示式匹配的行,類似於 grep 命令。
  • echo abcd |awk '/b.*d/ {print $0}'
    • 與上面相同,使用顯式 print 語句。$0 代表整行。
  • echo ab   cd |awk '/b.*d/ {print $2}'
    • 對於與正則表示式匹配的行,輸出第二個欄位。預設情況下,使用空格序列作為欄位分隔符。因此,輸出“cd”。
  • echo abcd,e |awk -F, '/b.*d/ {print $2}'
    • 對於與正則表示式匹配的行,輸出第二個欄位,由於 -F 選項,使用逗號作為欄位分隔符。因此,輸出“e”。
  • echo abcd,e |awk '{print toupper($0)}'
    • 輸出所有行的大寫字母。對於小寫字母,使用“tolower”。
  • echo a b c d | awk '{print $NF, $(NF-1)}'
    • 輸出最後一個欄位和倒數第二個欄位;NF 是欄位數。
  • echo ab cd | awk 'NF>=2'
    • 輸出欄位數為 2 或更多的行。
  • echo ab cd | awk '{print NF}'
    • 對於每一行,輸出其中的欄位數。
  • echo ab cd | awk 'length($2) > 1'
    • 輸出所有第二欄位長度大於 1 的行。
  • echo ab cd | awk '$2 ~ /cd/'
    • 輸出第二欄位與正則表示式匹配的所有行。
  • echo ab cd | awk '$1 ~ /ab/ && $2 ~ /cd/'
    • 與上面類似,但使用由“&&”連線的兩個子條件。支援 C 程式語言中已知的其他邏輯運算子。
  • cat file.txt | awk 'NR >= 100 && NR <= 500'
    • 輸出行號在指定範圍內的行(記錄)。因此,充當行號過濾器。
  • cat file.txt | awk 'NR == 1 || /reg.*pattern/'
    • 輸出第一行和與正則表示式匹配的行。
  • echo abcd | awk '{gsub(/ab/,"ef");print}'
    • 替換也稱為替換,類似於 sed 命令;gsub 中的“g”代表全域性。
  • awk 'BEGIN{for(i=1;i<6;i++) print sqrt(i)}'
    • 輸出 1、...、5 中整數的平方根。BEGIN{} 的使用確保即使沒有輸入行饋送到 awk,程式碼也會執行。for 迴圈使用熟悉的 C 語言語法,sqrt 是可用的多個數學函式之一。
  • awk 'BEGIN{printf "%i %.2f\n", 1, (2+3)/7}'
    • 支援來自 C 語言的熟悉函式 printf,作為不需要圍繞引數的括號的語句。
  • awk 'BEGIN{for(i=1;i<9;i++) a[i]=i^2; for(i in a) print i, a[i]}'
    • 在 awk 關聯陣列也稱為對映或字典的幫助下,輸出一對整數及其平方。輸出的順序是不確定的,這在關聯陣列中是常見的。awk 沒有其他程式語言中已知的陣列和列表的直接模擬。
  • cat file.txt | awk '{sum+=$1} END{print sum}'
    • 使用 END 關鍵字輸出第一個欄位(列)中值的總和。
  • awk 'BEGIN{system("dir")}'
    • 執行外部命令 dir;在沙箱模式下停用。
  • awk 'function abs(x) {return x < 0 ? -x : x} BEGIN{print abs(-4)}'
    • 定義和使用絕對值函式。顯示了 C 語言中已知的三元運算子的使用。

連結

輸出兩個檔案中共同的或獨有的行,前提是檔案已排序。如果檔案未排序,則輸出是不確定的。選項控制識別方式,例如僅輸出共同的行。

示例

  • seq 1 5 > file1; seq 3 7 > file2
    • 將整數序列 1...5 和 3...7 輸出到檔案以支援以下 comm 使用示例。
  • comm file1 file2
    • 如果檔案已排序,則輸出三列,第一列是 file1 中獨有的行,第二列是 file2 中獨有的行,第三列是兩個檔案中共同的行。列預設以製表符分隔,但製表符僅用於前導縮排,並且輸出的每一行都只有一列填充。
  • comm -23 file1 file2
    • 如果檔案已排序,則輸出 file1 中不在 file2 中的行。因此,對行執行集合差運算。開關表示要從輸出中省略的列。
  • comm -12 file1 file2
    • 如果檔案已排序,則輸出兩個檔案中都存在的行。因此,對行執行集合交運算。
  • printf "1\n1\n" > file1; printf "1\n" > file2; comm file1 file2
    • 第一行被評為兩個檔案中都存在的,而 file1 的第二行被評為 file1 中獨有的。因此,不僅考慮行內容,而且將重複行視為要匹配的獨立項來處理。
  • seq 1 5 > file1; seq 3 7 | comm file1 -
    • 使用連字元 (-) 表示標準輸入。

連結

將輸入拆分為輸出檔案。拆分可以由行數和正則表示式匹配驅動。

連結

輸出文字檔案中各行中的選定列(“欄位”),並指定列分隔符。另請參見 Cut 華夏公益教科書。

示例

  • cut -f1 file.txt
    • 輸出每一行的第一個欄位,使用製表符作為欄位分隔符。
  • echo a:b | cut -d: -f2
    • 輸出每一行的第二個欄位,使用冒號作為欄位分隔符。
  • echo a b c | cut -d" " -f1,3
  • echo a b c d e | cut -d" " -f1-3,5
  • echo a b c | cut -d" " -f3,2,1
    • 輸出“a b c”,忽略 -f 之後的反轉順序。
  • echo a b c d | cut -d" " -f2-
    • 輸出第二個和所有後續欄位,因此為“b c d”。
  • echo abcd | cut -c3,4
    • 不處理欄位,而是處理字元。因此,輸出“cd”。
  • echo abcdefgh | cut -c1-3,6-8
    • 輸出 abcfgh

連結

將製表符轉換為空格,預設情況下每個製表符為 8 個空格。另請參見 #unexpand.

連結

格式化文字,包括將段落重新排列為每行特定最大字元數。似乎沒有被 POSIX 覆蓋

連結

以不同於 #fmt 的方式限制每行最大長度。

連結

  • fold, opengroup.org
  • 4.3 fold 在 GNU Coreutils 手冊中,gnu.org

在字元編碼之間轉換。

示例

  • iconv -f ISO-8859-2 -t UTF-8 < in.txt > out.txt
    • 從 (-f) ISO-8859-2 轉換為 (-t) UTF-8。

連結

根據欄位將來自多個檔案的行合併在一起,假設這些檔案是根據用於合併的欄位排序的。

連結

新增行號。

連結

  • nl, opengroup.org
  • 3.3 nl 在 GNU Coreutils 手冊中,gnu.org

對於多個檔案,將對應於行號的行連線起來,就好像每個檔案是表格的一列,每個檔案行是表格的一行一樣。

連結

格式化輸入以供列印,包括帶有頁首和頁尾的分頁。

連結

sed,一個流編輯器,以其文字替換功能而聞名,支援正則表示式,但可以做更多。您可以在 Sed Wikibook 中瞭解更多資訊。

替換的單行示例

  • sed "s/concieve/conceive/" myfile.txt
    • 替換每行中 "concieve" 的第一次出現。
  • sed "s/concieve/conceive/g" myfile.txt
    • 替換所有出現,因為末尾有 "g"。
  • sed "s/concieve/conceive/g;s/recieve/receive/g" myfile.txt
    • 執行兩次替換。
  • echo "abccbd" | sed "s/a\([bc]*\)d/\1/g"
    • 輸出 "bccb"。使用 \( 和 \) 來標記一個組,並使用 \1 來引用替換部分中的組。
    • 可能只適用於 GNU sed;待驗證。
  • echo "abccbd" | sed -r "s/a([bc]*)d/\1/g"
    • 在 GNU sed 中,它與前面的示例做同樣的事情,只是使用 -r 來啟用擴充套件正則表示式,從而避免了在 "(" 前面放置反斜槓來表示分組的必要性。
    • -r 開關在 GNU sed 中可用,而在原始的 Unix sed 中不可用。
  • echo "a  b" | sed -r "s/a\s*b/ab/g"
    • 在 GNU sed 中,輸出 "ab"。使用 "\s" 來表示空格,並使用 "*" 來使前面的字元組迭代任意次數。需要 -r 來在 GNU sed 中啟用擴充套件正則表示式。
  • sed "s/\x22/'/g" myfile.txt
    • 在 GNU sed 中,將每個引號替換為一個單引號。\x22 指的是十六進位制 ASCII 值為 22 的字元,即引號。
  • echo Hallo | sed "s/hallo/hello/gi"
    • 忽略字元大小寫,因為末尾有 "i"。不保留大小寫,輸出 "hello" 而不是 "Hello"。
  • echo a2 | sed "s/[[:alpha:]]/z/g"
    • 輸出 z2,使用 "[[:alpha:]]",它代表任何字母。注意,字元類在手冊中列為 "[:alpha:]",帶有單個 "["。

連結

對檔案中的行進行排序,輸出排序後的行,並將輸入保持不變。

示例

  • sort file.txt
    • 按字母順序對檔案進行排序。
  • sort file.txt file2.txt
    • 按字母順序對兩個檔案的行進行排序,輸出來自兩個檔案的一個排序後的行流。
  • cat file.txt | sort
    • 對 cat 建立的輸入流進行排序。因此,等效於 sort file.txt。
  • sort -n file.txt
    • 對檔案進行數字排序。因此,12 放在 2 之後,而字母順序則不是這樣。
  • sort -r file.txt
    • 按相反順序對檔案進行排序。因此,b 放在 a 之前。
  • sort -k5,5 file.txt
    • 透過 -k 對檔案按第 5 個欄位(列)進行排序。
  • sort -t, -k5,5 file.txt
    • 如上所述,透過 -t 使用逗號 (,) 作為欄位分隔符。
  • sort -k5,5 -k3,3 file.txt
    • 首先按第 5 個欄位對檔案進行排序,然後按第 3 個欄位進行排序。
  • sort -k5,5 -k3,3n file.txt
    • 如上所述,但當按第 3 個欄位排序時,透過附加的 "n" 按數字順序進行排序。
  • sort -k5 file.txt
    • 首先按第 5 個欄位對檔案進行排序,然後對所有剩餘欄位進行排序,忽略排序目的的第 1-4 個欄位。
  • sort -u file.txt
    • 對檔案進行排序,刪除重複的行,從而確保每行輸出都是唯一的。
  • sort -u -k5,5 file.txt
    • 按第 5 個欄位對檔案進行排序,僅保留具有相同鍵的每組行中的一個行,其中鍵是第 5 個欄位。

連結

執行拼寫檢查。似乎在 POSIX 中不存在。

連結

執行字元對映或“轉換”,以及更多操作。對於某些任務,它比 sed 更簡潔。

示例

  • echo "a:b:c:d" | tr : \\n
    • 透過冒號 (:) 分割成多行。冒號不會出現在輸出中。
  • echo "a b c d" | tr " " \\n
    • 透過空格分割成多行。
  • echo "abba" | tr ab cd
    • 將 a 替換為 c,將 b 替換為 d。因此,產生 cddc。
  • echo "a,b:c,d:e" | tr ,: :,
    • 交換逗號和冒號。因此,產生 a:b,c:d,e。
  • echo "a b c d" | tr -d " "
    • 從輸入中刪除空格,輸出 abcd。-d 代表刪除。
  • echo "a,b,c:d:e" | tr -dc ,
    • 僅保留逗號和冒號。-c 代表補集。因此,產生 ,,::.
  • echo "a,,,b,c::d" | tr -s ,
    • 將逗號序列替換為一個逗號,將冒號序列替換為一個冒號。-s 代表壓縮。因此,產生 a,b,c:d。

連結

將空格轉換為製表符,預設情況下每個製表符佔 8 個空格。

連結

從每個相同行塊中輸出單行,等等。理想情況下與排序後的輸入一起使用。您可以在 Uniq 華夏公益教科書中瞭解更多資訊。

示例

  • uniq file.txt
    • 對於相鄰的一個或多個相同的行,只輸出其中一行。
  • sort file.txt | uniq
    • 對相同行進行排序,然後只輸出其中一行。排序確保最初不相鄰但相同的行變得相鄰。
  • sort file.txt | uniq -u
    • 只輸出單行塊。
  • sort file.txt | uniq -d
    • 輸出每塊的多行塊中的單行,過濾掉單行。
  • sort file.txt | uniq -c
    • 在每行之前加上塊大小。
  • sort file.txt | uniq -c | sort
    • 在每行之前加上塊大小,並按塊大小對結果進行排序。由於 uniq 輸出的大小透過空格縮排,因此排序效果很好,即使是按字母順序排列。
  • sort file.txt | uniq -u -d
    • 在 GNU uniq 中,不輸出任何內容,因為每個選項都充當過濾器,組合在一起後它們會過濾掉所有內容。

連結

華夏公益教科書