3

假设我有一个配置文件可以是下面两种格式之一(简短的例子,但基本上第一种格式是一个太长的行,你必须使用行继续符,而第二种格式只是一个很长的没有续行的行)

data1=x data2=y data3=z \
datakey

第二种格式

data=1 data2=y data3=z datakey

我想data1=x data2=y data3=x datakey为这两种情况匹配确切的行。有没有简单的方法来做到这一点?

4

5 回答 5

4

read解释\为行继续符:

while read line ; do
    if [[ $line == 'data=1 data2=y data3=z datakey' ]] ; then
        echo "$line"
    fi
done
于 2012-10-08T06:17:11.477 回答
1

也许 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
于 2012-10-08T06:11:08.077 回答
1

我会使用 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)。
  • 然后,当行不以 a 结尾时\,删除所有的\和换行符(thes/\\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将保持空间复制到打印的模式空间)。

于 2012-10-08T07:10:43.827 回答
0
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
> 
于 2012-10-08T06:24:23.840 回答
0

我喜欢上面的 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

解释:

  1. re=search-string设置要查找的正则表达式。
  2. ls=ls""$0将新行连接到 ls(行搜索),还将原始行存储到 lp(行打印),如上面的 sed 示例。
  3. /\\$/检查输入是否有连续字符,如果有,substr() 会从 ls 中删除多余的字符,lp 会附加一个换行符以保持原始格式。最后next 导致 awk 读取下一行并从第一条规则开始。
  4. ls~i在 line-search 中搜索 re ,如果它匹配 prints lp,如果愿意,可以添加一个开关来 print ls
  5. 最后(不是倒数第二个)在没有续行时重置 ls & lp。
  6. END 是特殊规则,在这里用于检测ls仍然有分配的值,这意味着续行在 EOF 处。搜索正则表达式,当它匹配时,它会切断上面添加的额外换行符。

现在,没有人会在一行的末尾写“\”,不是吗?

于 2015-10-09T16:15:59.763 回答