繁体   English   中英

使用SED命令中的变量在两个模式之间选择线

[英]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文件到一个变量,然后echosed过滤,为什么你的命令不工作的原因是因为你没有引述文件内容可变, fileCecho 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM