假设我有一个配置文件可以是下面两种格式之一(简短的例子,但基本上第一种格式是一个太长的行,你必须使用行继续符,而第二种格式只是一个很长的没有续行的行)
data1=x data2=y data3=z \
datakey
第二种格式
data=1 data2=y data3=z datakey
我想data1=x data2=y data3=x datakey
为这两种情况匹配确切的行。有没有简单的方法来做到这一点?
read
解释\
为行继续符:
while read line ; do
if [[ $line == 'data=1 data2=y data3=z datakey' ]] ; then
echo "$line"
fi
done
也许 grep 不是解决此类问题的最佳工具。
您可以加入所有以结尾的行\
,然后像往常一样 grep 该输出:
假设你有一个文件:
$> cat text
1
2
fasdfasdf
data1=x data2=y data3=z \
datakey
fasfd
sdf
所以你可以加入所有以 结尾的行\
:
$> awk '{line = $0}; /.*\\/ {split($0,tmp,"\\"); line = tmp[1]; getline; line = line $0}; { print line }' text
1
2
fasdfasdf
data1=x data2=y data3=z datakey
fasfd
sdf
我会使用 sed 创建一个没有结尾的输出\
:
sed -e ':begin;/\\$/{N;bbegin};s/\\\n//g' your_file
然后你可以grep它:
sed -e ':begin;/\\$/{N;bbegin};s/\\\n//g' your_file | grep your_pattern
你甚至可以在 sed 中完成这一切:
sed -n -e ':begin;/\\$/{N;bbegin};s/\\\n//g;/your_pattern/p' your_file
更新:
上面解释一下:
:begin
设置一个标签,我可以使用命令分支(转到)b
。/\\$/{N;bbegin}
如果当前行以\
( /\\$/
) 结尾,则将下一行附加到缓冲区 ( N
) 并转到开始 ( bbegin
)。\
,删除所有的\
和换行符(the
s/\\n//g`)。-n
选项告诉 sed no 打印脚本末尾的行。/your_pattern/p
如果匹配,则打印该行your_pattern
。更新2:
我们甚至可以做得更好并显示文件的原始行:
sed -n -e ':begin;/\\$/{N;bbegin};h;s/\\\n//g;/your_pattern/{g;p}' your_file
这样做是在删除 \
和换行符之前,它将数据保存在保持空间(h
)中,如果行匹配,它会打印保存的数据(g
将保持空间复制到打印的模式空间)。
awk -v i="data1=x data2=y data3=z datakey" '{x=x" "$0}END{y=match(x," "i);if(y) print "yes its a match"}' temp
测试如下:
> cat temp
data1=x data2=y data3=z
datakey
> awk -v i="data1=x data2=y data3=z datakey" '{x=x" "$0}END{y=match(x," "i);if(y) print "yes its a match"}' temp
yes its a match
>
我喜欢上面的 sed 示例,并没有注意到已经提交的 awk 示例。这是 awk (nawk) 版本,它保留格式并处理多个续行和文件结尾。
nawk -v re="search-string" \
'{ls=ls""$0;lp=lp""$0}
/\\$/{ls=substr(ls,1,length(ls)-1);lp=lp"\n";next}
ls~re{print lp}
{lp=ls=""}
END{if (ls ~ re)print substr(lp,1,length(lp)-1)}' input-file
解释:
现在,没有人会在一行的末尾写“\”,不是吗?