【问题标题】:What's confusing both grep and ack?什么是混淆 grep 和 ack?
【发布时间】:2021-02-22 22:13:48
【问题描述】:

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

在解压后的文件夹中,我得到以下结果:

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

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');

发生了什么事?

[编辑澄清]:为什么第 3 行结果没有文件名,没有行号?为什么第 4 行和第 5 行的结果甚至不包含dsexample

注意:使用 ack 3.40 和 grep 2.16

【问题讨论】:

  • Stack Overflow 用于编程问题,而不是关于使用或配置 Unix 及其实用程序的问题。 Unix & LinuxSuper User 将是解决此类问题的更好地方。
  • 有什么问题?是因为你得到了多行匹配的输出吗?
  • 我的猜测是有一个 CR 行分隔符,并且正在将其转换为换行符。
  • 输出应该是什么?
  • 我很感激需要一个帐户来下载文件并不方便......但同时我根本不想更改它们,因为我不知道这些有什么特别之处混淆 ack 和 grep 的文件。我添加了另一个下载位置here

标签: linux unix grep ack


【解决方案1】:

我不应该为这个答案获得任何荣誉 - 这完全是关于行尾。

我多年来一直知道 Windows 行尾 (CR-LF) 和 Linux 行尾(仅限 LF),但我从未听说过 Legacy MAC 行尾(仅限 CR)...后者真的让 ack、grep 感到不安,而且我敢肯定还有很多其他工具。

dos2unixunix2dos 对 Legacy MAC 格式的文件没有影响 - 但是使用这个漂亮的小 endline 工具后,我最终可以为源文件带来一些一致性:

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

现在,ack 和 grep 快乐多了。

【讨论】:

  • 在过去的许多不同操作系统中,简单的回车曾经相当普遍; Commodore 8 位使用相同的约定。但随着 C 和 UNIX 的主导地位,它几乎消失了。 pre-X MacOS 是最后的坚持者之一。当文件被发送到屏幕或打印机时,任何这样的单字符行结束标记都需要驱动程序中的一些转换逻辑来输出这两个字符; CP/M 简化了代码,代价是要求将两个字符实际存储在每个文件的每一行的末尾。 DOS 和 Windows 继承了该设计决策。
【解决方案2】:

让我们看看哪些文件包含dsexamplegrep -l不打印内容,只打印文件名:

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

好的,那么,file 表明他们有 CR 行终止符。 (它会说 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

与我之前评论的不同,Contents.m 很好。让我们看看另一个,它是如何打印的:

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

grep 的输出实际上是整个文件,因为grep 不认为普通的 CR 会换行——整个文件只有一行。如果我们将 CR 更改为 LF,我们会看得更清楚,或者可以只计算行数:

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

这些是那里最长的行,按顺序排列:

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

每个结尾都有一个 CR,光标移回行首,部分覆盖之前的输出,所以你得到:

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

(该行的分号后面有一个空格,所以e 也被覆盖了。我检查了。)

有人说dos2unix 无法处理这个问题,而且它们不是 DOS 或 Windows 文件,为什么要这样做。不过,你可以在 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

我认为只是 .m 文件有问题,因此 *.m 在循环中。那里至少有一个 PDF 文件,我们不想破坏它。虽然在那里检查了file,但即使您只是在* 上运行循环也应该是安全的。

【讨论】:

    【解决方案3】:

    看起来 ack 和 grep 都被文件中的行尾弄糊涂了。在您的文件上运行file *.m。您会看到有些文件有正确的换行符,有些文件有 CR 行终止符。

    如果你清理你的行尾,事情应该没问题。

    【讨论】:

    • 你是对的,所有文件不使用相同的约定,并且混合了行尾...请注意,这些不是我的文件...只是任何人都可以使用的一些开源内容,所以这超出了我的控制 话虽如此 - 我在 Linux 和 Windows 上从 grep 和 ack 得到了完全相同的结果(来自 ezwinports 的 grep),所以行尾可能不是根本原因......我已尝试将文件转换为一致的表示,但仍然得到相同的结果...
    • 我很确定你会发现它是行尾。如果您可以将其追溯到 ack 中的其他错误,请在github.com/beyondgrep/ack3 报告它(我是作者)。
    • 我会再调查一下,让你知道!我认为这不是 ack 中的错误,因为 grep 的行为几乎完全相同......所以它可能是源文件中的东西......我发现第 3、4 和 5 行输出来自位于两个文件中的匹配项:dsexample1.mdsexample2.m - 因此您可以删除除这两个文件之外的所有内容进行调查。
    • 我无法分享仅限于搜索格式良好的 2 个文件的结果,所以你必须相信我.... 但是在 dos2unixunix2dos 之后搜索这两个文件产生完全相同的结果。
    • 我发现,如果我使用--heading 而不是--no-heading 运行 ack,如 OP 中所示,那么至少找到匹配项的文件名会正确打印。虽然仍然没有行号。第三场比赛实际上似乎来自demoLPandBP.m——我以为是来自dsexample1.m,但我错了。该文件实际上包含 7 个出现 (!) 的 dsexample
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-12
    • 1970-01-01
    • 2015-02-05
    • 1970-01-01
    • 2012-04-04
    • 2010-09-16
    • 2021-06-05
    相关资源
    最近更新 更多