I'm new to shell scripting. My requirement is to retrieve lines between two pattern, its working fine if I run it from the terminal without using variables inside sed cmd. But the problem arises when I put all those below cmd in a file and tried to execute it.
#!/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"
If I use the below cmd in the terminal it works fine
sed -n '/ajp-qdcls2228.us.qdx.com%2F156.30.35.204-8009-34/,/2017-01-03 23:00/ p' test.log
Please suggest a workaround.
答案 0 :(得分:2)
如果我们搁置一下这个事实你不应该cat
一个文件到一个变量,然后echo
它用于sed
过滤,你的命令是不工作是因为fileC
时你没有引用文件内容变量echo
。这将把多个空格字符组合在一起并将它们转换为单个空格。因此,您从文件中丢失新行,以及多个空格,标签等。
要修复它,你可以写:
fileC=$(cat test.log)
output=$(echo "$fileC" | sed -n "/$word/,/$upto/p")
请注意fileC
周围的双引号(以及固定的sed
表达式,类似于第二个示例)。如果没有引号(尝试echo $fileC
),您的fileC
会被扩展(使用默认的IFS
)成一系列单词,每个单词都是echo
的一个参数,而{echo
1}}只会打印用单个空格分隔的单词。此外,如果文件包含一些通配符(如*
),那么模式也会扩展。这是common bash pitfall。
更好的来写这样:
output=$(sed -n "/$word/,/$upto/p" test.log)
如果您的模式包含一些sed
元字符,那么在使用sed
之前,您应该escape them,如下所示:
escape() {
sed 's/[^^]/[&]/g; s/\^/\\^/g' <<<"$1";
}
output=$(sed -n "/$(escape "$word")/,/$(escape "$upto")/ p" test.log)
答案 1 :(得分:1)
正确的方法将是:
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
但在我们看到您的示例输入和输出之前,我们无法确定您需要匹配的内容(全行,部分行,一行中的所有文本等)或您想要的内容print(包括分隔符,排除一个,排除两者等)。