[英]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.