[英]Select lines between two patterns using variables inside SED command
我是shell腳本的新手。 我的要求是檢索兩個模式之間的行,如果我從終端運行它而不使用sed cmd中的變量,它的工作正常。 但是,當我將cmd下面的所有內容放在文件中並嘗試執行它時,問題就出現了。
#!/bin/sh
word="ajp-qdcls2228.us.qdx.com%2F156.30.35.204-8009-34"
upto="2017-01-03 23:00"
fileC=`cat test.log`
output=`echo $fileC | sed -e "n/\$word/$upto/p"`
printf '%s\n' "$output"
如果我在終端使用下面的cmd它工作正常
sed -n '/ajp-qdcls2228.us.qdx.com%2F156.30.35.204-8009-34/,/2017-01-03 23:00/ p' test.log
請建議一個解決方法。
如果我們撇開了一會兒事實上,你不應該cat
文件到一個變量,然后echo
它sed
過濾,為什么你的命令不工作的原因是因為你沒有引述文件內容可變, fileC
當echo
ING。 這將把多個空格字符組合在一起並將它們轉換為單個空格。 因此,您將丟失文件中的換行符 ,以及多個空格,制表符等。
要解決它,你可以寫:
fileC=$(cat test.log)
output=$(echo "$fileC" | sed -n "/$word/,/$upto/p")
注意fileC
周圍的雙引號(和一個固定的sed
表達式,類似於你的第二個例子)。 如果沒有引號(嘗試echo $fileC
),你的fileC
被擴展(使用默認的IFS
)為一系列單詞,每個單詞都是echo
一個參數, echo
將只打印用單個空格分隔的單詞。 此外,如果文件包含一些通配符(如*
),那么這些模式也會擴展 。 這是一個常見的重擊陷阱 。
更好的是這樣寫:
output=$(sed -n "/$word/,/$upto/p" test.log)
如果你的模式包含一些sed
元字符,那么在使用sed
之前你應該真正逃脫它們 ,如下所示:
escape() {
sed 's/[^^]/[&]/g; s/\^/\\^/g' <<<"$1";
}
output=$(sed -n "/$(escape "$word")/,/$(escape "$upto")/ p" test.log)
正確的方法將是這樣的:
word="ajp-qdcls2228.us.qdx.com%2F156.30.35.204-8009-34"
upto="2017-01-03 23:00"
awk -v beg="$word" -v end="$upto" '$0==beg{f=1} f{print; if ($0==end) exit}' file
但在我們看到您的樣本輸入和輸出之前,我們無法確定您需要匹配的內容(全行,部分行,一行中的所有文本等)或您要打印的內容(包括分隔符,排除一個,排除兩者等)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.