简体   繁体   English

grep 和 ack 有什么令人困惑的地方?

[英]What's confusing both grep and ack?

Try this: download https://www.mathworks.com/matlabcentral/fileexchange/19-delta-sigma-toolbox试试这个:下载https://www.mathworks.com/matlabcentral/fileexchange/19-delta-sigma-toolbox

In the unzipped folder, I get the following results:在解压缩的文件夹中,我得到以下结果:

ack --no-heading --no-break --matlab dsexample ack --no-heading --no-break --matlab dsexample

Contents.m:56:%   dsexample1      - Discrete-time lowpass/bandpass/quadrature modulator.
Contents.m:57:%   dsexample2      - Continuous-time lowpass modulator.
dsexample1(dsm, LiveDemo); 
fprintf(1,'Done.\n');
adc.sys_cs = sys_cs;

grep -nH -R --include="*.m" dsexample grep -nH -R --include="*.m" dsexample

Contents.m:56:%   dsexample1      - Discrete-time lowpass/bandpass/quadrature modulator.
Contents.m:57:%   dsexample2      - Continuous-time lowpass modulator.
dsexample1(dsm, LiveDemo); d center frequency larger Hinfation Script
fprintf(1,'Done.\n');c = c;formed.s of finite op-amp gain and capacitorased;;n for the input.
adc.sys_cs = sys_cs;snr;seed with CT simulations tora states used in the d-t model_amp); Response');

What's going on?这是怎么回事?

[Edit for clarification]: Why is there no file name, no line number on the 3rd line result? [编辑澄清]:为什么第 3 行结果没有文件名,没有行号? Why results on the 4th and 5th line do not even contain dsexample ?为什么第 4 行和第 5 行的结果甚至不包含dsexample

NB: using ack 3.40 and grep 2.16注意:使用 ack 3.40 和 grep 2.16

I do not deserve any credits for this answer - It is all about line endings.我不值得这个答案的任何功劳 - 这都是关于行尾的。

I have known for years about Windows line endings (CR-LF) and Linux line endings (LF only), but I had never heard of Legacy MAC line endings (CR only)... The latter really upsets ack, grep, and I'm sure lots of other tools.我已经知道 Windows 行尾(CR-LF)和 Linux 行尾(仅 LF),但我从未听说过 Legacy MAC 行尾(仅 CR)......后者真的让 ack、Z4A037ZC、6153C86D49472 '确定很多其他工具。

dos2unix and unix2dos have no effect on files with Legacy MAC format - But after using this nifty little endline tool, I could eventually bring some consistency to the source files: dos2unixunix2dos对 Legacy MAC 格式的文件没有影响 - 但是在使用这个漂亮的小端线工具之后,我最终可以为源文件带来一些一致性:

endlines : 129 files converted from :
              - 23 Legacy Mac (CR)
              - 105 Unix (LF)
              - 1 Windows (CR-LF)

Now, ack and grep are much happier.现在,ack 和 grep 开心多了。

Let's see what files contain dsexample , grep -l doesn't print the contents, just file names:让我们看看哪些文件包含dsexamplegrep -l不打印内容,只是文件名:

$ grep -l dsexample *
Contents.m
demoLPandBP.m
dsexample1.m
dsexample2.m

Ok, then, file shows that they have CR line terminators.好的,那么, file显示他们有 CR 行终止符。 (It would say "CRLF line terminators" for Windows files.) (它会说 Windows 文件的“CRLF 行终止符”。)

$ file Contents.m demoLPandBP.m dsexample*
Contents.m:    ASCII text
demoLPandBP.m: ASCII text, with CR line terminators
dsexample1.m:  ASCII text, with CR line terminators
dsexample2.m:  ASCII text, with CR line terminators

Unlike what I commented about before, Contents.m is fine.与我之前评论的不同, Contents.m很好。 Let's look at another one, how it prints:让我们看看另一个,它是如何打印的:

$ grep dsexample demoLPandBP.m 
dsexample1(dsm, LiveDemo); d center frequency larger Hinf

The output from grep is actually the whole file, since grep doesn't consider the plain CR as breaking a line -- the whole file is just one line. grep 中的grep实际上是整个文件,因为grep不认为普通的 CR 会中断一行——整个文件只是一行。 If we change CRs to LFs, we see it better, or can just count the lines:如果我们将 CR 更改为 LF,我们会看得更清楚,或者可以只计算行数:

$ grep dsexample demoLPandBP.m | tr '\r' '\n' | wc -l
51

These are the longest lines there, in order:这些是那里最长的线路,按顺序:

%% 5th-order lowpass with optimized zeros and larger Hinf
dsm.f0 = 1/6;   % Normalized center frequency
dsexample1(dsm, LiveDemo); 

With a CR in the end of each, the cursor moves back to the start of the line, partially overwriting the previous output, so you get:每个末尾都有一个 CR,cursor 移回行首,部分覆盖之前的 output,因此您得到:

dsexample1(dsm, LiveDemo); d center frequency larger Hinf

(There's a space after the semicolon on that line, so the e gets overwritten too. I checked.) (该行的分号后面有一个空格,所以e也被覆盖了。我检查了。)

Someone said dos2unix can't deal with that, and well, they're not DOS or Windows files anyway so why should it.有人说dos2unix无法处理,好吧,它们不是 DOS 或 Windows 文件,为什么要这样做。 You could do something like this, though, in Bash:不过,您可以在 Bash 中执行以下操作:

for f in *.m; do
    if [[ $(file "$f") = *"ASCII text, with CR line terminators" ]]; then
        tr '\r' '\n' < "$f" > tmptmptmp &&
        mv tmptmptmp "$f"
    fi
done

I think it was just the .m files that had the issue, hence the *.m in the loop.我认为只是.m文件有问题,因此*.m在循环中。 There was at least one PDF file there, and we don't want to break that.那里至少有一个 PDF 文件,我们不想破坏它。 Though with the check on file there, it should be safe even if you just run the loop on * .尽管在那里检查了file ,但即使您只是在*上运行循环,它也应该是安全的。

It looks like both ack and grep are getting confused by the line endings in the files.似乎 ack 和 grep 都被文件中的行结尾弄糊涂了。 Run file *.m on your files.在您的文件上运行file *.m You'll see that some files have proper linefeeds, and some have CR line terminators.您会看到有些文件有正确的换行符,有些文件有 CR 行终止符。

If you clean up your line endings, things should be OK.如果你清理你的行尾,事情应该没问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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