Sed

Posted by Adam on August 24, 2022
```bash echo "FileName 123 1277" | sed 's/\S/X/g' # XXXXXXXX XXX XXXX echo "FileName 123 1277" | sed 's/[^[:space:]]/X/g' # XXXXXXXX XXX XXXX echo "FileName 123 1277" | sed 's/\s/X/g' # FilenameX123X1277 echo "FileName 123 1277" | sed 's/[[:space:]]/X/g' # FileNameX123X1277 echo "FileName 123 1277" | sed 's/[0-9]/X/g' # FileName XXX XXXX echo "FileName 123 1277" | sed 's/[a-z]/X/g' # FXXXNXXX 123 1277 echo "FileName 123 1277" | sed 's/[A-Z]/X/g' # XileXame 123 1277 echo "FileName 123 1277" | sed 's/.*\([0-9]\{3\}\).*/\1/g' # 277 echo "FileName 123 1277" | sed 's/.*\([0-9]\{3\}\)\s.*/\1/g' #123 echo "FileName 123 1277" | sed 's/.*\s\([0-9]*\)\s.*/\1/g' #123 echo "FileName 123 1277" | sed 's/.*\s\([0-9]*\)$/\1/g' #1277 echo "FileName 123 1277" | sed 's/\([0-9]\)\1/X/g' # FileName 123 12X echo "FileName 123 1277" | sed 's/.*[A-Z]\(.*\)[A-Z].*/\1/g' # ile ``` --- 在使用 `sed`(流編輯器)時,需要注意以下一些符號和特殊字符,它們在正規表達式和`sed`指令中具有特殊的含義: 1. **斜杠 `/`:** 用於分隔`sed`指令的不同部分,如 `s/old/new/g` 中的 `/`。 2. **撇號 `'` 或 `"`:** 用於包裹`sed`指令,以防止空格和特殊字符被Shell解釋。例如:`sed 's/old/new/g'`。 3. **反斜杠 `\`:** 用於轉義特殊字符,使它們失去正規表達式中的特殊含義。例如:`\(` 表示左括號。 4. **點 `.`:** 匹配任何單個字符,例如 `.` 表示匹配任何字符。 5. **星號 `*`:** 匹配前一個字符的零次或多次重複,例如 `a*` 表示零個或多個連續的字母 'a'。 6. **方括號 `[]`:** 用於定義字符類別,例如 `[0-9]` 表示匹配任何一個數字。 7. **插入符號 `^` 和美元符號 `$`:** 分別用於匹配行的開頭和結尾,例如 `^start` 表示以 'start' 開頭的行。 8. **大括號 `{}`:** 用於指定重複次數,例如 `a{3}` 表示匹配 'aaa'。 9. **反斜杠後接數字 `\1`, `\2`:** 在替換字符串中,引用前面捕獲的分組。例如,`s/\(pattern\)/\1/` 可以用來複製 `pattern`。 10. **分號 `;`:** 用於分隔多個`sed`指令,允許在單個命令行中執行多個`sed`操作。 11. **逗號 `,`:** 在範圍地址中使用,例如 `1,5d` 表示刪除第1行到第5行。 這些是一些常見的`sed`中使用的特殊字符和符號。在使用 `sed` 的時候,請格外小心確保正確使用這些符號以及它們的正確轉義方式。 `sed`(Stream Editor)是一個強大的文本處理工具,用於在文本流中執行轉換操作。以下是一些常用的 `sed` 命令的例子: 1. **替換字串:** ```bash echo "Hello, this is old_string." | sed 's/old_string/new_string/g' ``` 2. 刪除行: ```bash echo -e "Line 1\nLine 2\nLine 3" | sed '2d' ``` 3. 指定範圍內的操作: ```bash echo -e "Line 1\nLine 2\nLine 3" |sed '2,5d' ``` 這將刪除 `input.txt` 中第 2 到第 5 行的內容。 4. 在特定行後插入新行: ```bash echo -e "Line 1\nLine 2" | sed '2a\This is a new line' ``` 5. 取代特定行: ```bash echo -e "Line 1\nLine 2\nLine 3" | sed '3c\This is the new line' ``` 這將取代 `input.txt` 中的第三行為新內容。 6. 只顯示特定行: ```bash echo -e "Line 1\nLine 2\nLine 3" | sed -n '2p' ``` 這將只顯示 `input.txt` 中的第二行。 7. **條件判斷並替換:** ```bash sed '/pattern/s/old_string/new_string/g' input.txt ``` 這將只有在行中包含 `pattern` 的情況下,才替換該行內的 `old_string` 為 `new_string`。 ```bash # This is an ab example. # Another line with xy. echo -e "This is an ab example.\nAnother line with xy." | sed '/[a-zA-Z]\{2\}/s/ab/new_string/g' # This is an new_string example. # Another line with xy. ``` 8. **反向引用:** ```bash sed 's/\(pattern\) \(pattern\)/\2 \1/g' input.txt ``` 這將交換 `input.txt` 中每行中第一個和第二個 `pattern` 的位置。 這僅僅是 `sed` 命令的一些基本示例。`sed` 提供了豐富的功能和選項,你可以根據需要來進行更複雜的操作,如正則表達式、多檔案處理等。詳細的用法可以參考 `sed` 的官方文件或其他教學資源。 ```bash # apple banana # orange apple # banana orange echo -e "apple banana\norange apple\nbanana orange" | sed 's/\(apple\) \(banana\)/\2 \1/g' # banana apple # orange apple # banana orange ``` ### Regex 符合的數字 ```bash echo "filename123_1277" | sed 's/.*\([0-9]\+\).*/\1/' seq 11 20 | sed '/^1\S/{h;d};/^2/G' # ^1\S 為比對的Regex # {h;d} 為複製和刪除 # ; 分隔 # ^2 為目標的Regex # G 代表串接在目標下 ``` ### POSIX 字符集 [[:alnum:]]:匹配任何字母或數字字符。 [[:alpha:]]:匹配任何字母字符。 [[:blank:]]:匹配空格和制表符。 [[:cntrl:]]:匹配控制字符。 [[:digit:]]:匹配數字字符。 [[:graph:]]:匹配非空白字符。 [[:lower:]]:匹配小寫字母字符。 [[:print:]]:匹配可打印字符。 [[:punct:]]:匹配標點符號字符。 [[:space:]]:匹配空白字符,包括空格、制表符、換行符等。 [[:upper:]]:匹配大寫字母字符。 [[:xdigit:]]:匹配十六進制數字字符。 ```bash echo -e "ab 123" | sed 's/[[:alnum:]]/X/g' # XX XXX echo -e "abc def" | sed 's/[[:space:]]/X/g' # abcXdef # 將文本中的所有小寫字母替換為大寫字母 echo "Hello, world!" | sed 's/[[:lower:]]/\U&/g' # HELLO, WORLD! # 將文本中的所有大寫字母替換為小寫字母 echo "Hello, WORLD!" | sed 's/[[:upper:]]/\L&/g' # hello, world! ``` ### 匹配數字或符號 要在 `sed` 中匹配數字或符號,並且其數量在1到3之間,你可以使用正則表達式的 `{min,max}` 語法來指定數量範圍。以下是一個示例,展示如何在 `sed` 中實現這種匹配: ```bash sed -n '/^[[:digit:][:punct:]]\{1,3\}$/p' file.txt ``` 這個命令使用 `-n` 選項禁止預設的輸出,然後使用正則表達式 `/^[[:digit:][:punct:]]\{1,3\}$/` 來匹配行,該行中的內容包含數字或標點符號,且數量在1到3之間。 在這個正則表達式中: - `^[[:digit:][:punct:]]`:匹配以數字或標點符號開始的字符。 - `\{1,3\}`:指定前面的字符類別可以出現1到3次。 這樣,該正則表達式將匹配包含1到3個數字或標點符號的行。如果你要對其他內容進行匹配,只需調整正則表達式的內容。同樣地,請注意 `sed` 的正則表達式可能會因版本和上下文而有所不同,因此可能需要進行微調。 ### 非數字和非標點符號 ```bash grep '[^[:digit:][:punct:]]' file.txt ``` ### [找到指定行保留該行,但刪除該行之下的兩行](https://sed.js.org/?snippet=k7xyzp) ```bash sed '/pattern/,+2 { /pattern/!d }' inputfile > outputfile ``` ### [刪除指定行A 及指定行B 之間的內容](https://sed.js.org/?snippet=eqxkzK) ```bash sed '/A/,/B/ { /A/b; /B/b; d; }' inputfile > outputfile # A:該行的判斷依據 # B:該行的判斷依據 ``` ### CRLF 換成 LF ```bash sed -i 's%\r%%g' your_file.txt ``` ### 替換 Json 字串欄位內容 ```bash #!/bin/bash updateJsonString() { local jsonFile="$1" local fieldName="$2" local newValue="$3" sed "s/\"${fieldName}\":[[:blank:]]*\".*\"\([,]*\)/\"${fieldName}\": \"${newValue}\"\1/" "${jsonFile}" sed -i "s/\"${fieldName}\":[[:blank:]]*\".*\"\([,]*\)/\"${fieldName}\": \"${newValue}\"\1/" "${jsonFile}" } ```