Sed
使用 sed 和正則表達式從文件中提取數據
我有一個使用 BusyBox 在嵌入式 Linux 上執行的系統。有一個 YAML 配置文件“cfg.yaml”,其中包含如下內容:
range: tcpportmin: 10000 tcpportmax: 20000
我需要從文件中提取一些值。例如’tcpportmin’參數的值,即'10000’。我是通過腳本來完成的。
當我在一個小的“cfg.yaml”文件上執行這段程式碼時,一切都很好:
RANGE=`cat cfg.yaml` TCP_PORT_MIN=`echo $RANGE | sed "s/.*tcpportmin: \([[:digit:]]*\).*/\1/"` echo $TCP_PORT_MIN # Output: # 10000
但是真正的“cfg.yaml”文件的大小是幾百千字節,在這種情況下會引發錯誤:
/test.sh: line 211: echo: Argument list too long
如果我直接對文件應用相同的 sed 命令,結果是錯誤的:
TCP_PORT_MIN=`sed "s/.*tcpportmin: \([[:digit:]]*\).*/\1/" cfg.yaml` echo $TCP_PORT_MIN # Output: # range: 10000 tcpportmax: 20000
如果我嘗試在一行中使用多個 sed 命令,結果為空:
TCP_PORT_MIN=`sed -e "s/.*tcpportmin: \([[:digit:]]*\).*/\1/" -e "s/.*\([[:digit:]]*\).*/\1/p" cfg.yaml` echo $TCP_PORT_MIN # Output: # <Nothing>
僅供參考,我係統上 sed 命令的幫助螢幕:
BusyBox v1.15.3 (2018-08-13 13:52:22 NOVT) multi-call binary Usage: sed [-efinr] SED_CMD [FILE]... Options: -e CMD Add CMD to sed commands to be executed -f FILE Add FILE contents to sed commands to be executed -i Edit files in-place -n Suppress automatic printing of pattern space -r Use extended regex syntax If no -e or -f is given, the first non-option argument is taken as the sed command to interpret. All remaining arguments are names of input files; if no input files are specified, then the standard input is read. Source files will not be modified unless -i option is given.
**我的問題是:**如何使用 sed 命令從文件中提取值?
如果您知道只有一行匹配,那麼正確的方法是
sed -n 's/ *tcpportmin: \([[:digit:]]*\).*/\1/p' cfg.yaml
該
-n
標誌禁止所有輸出,除了由顯式 sed 命令觸發的輸出,例如p
. 因此,上面的 sed 只輸出它進行替換的行。您可以將輸出保存在變數中
TCP_PORT_MIN=$(sed -n 's/ *tcpportmin: \([[:digit:]]*\).*/\1/p' cfg.yaml)
$()
請注意,為了可讀性和嵌套,您應該使用反引號而不是反引號。