2017-09-25 76 views
0

我想在BASH中使用csplit将文件在1500-1600年间分隔为多个分隔符。为什么'csplit`和`grep`不一致就是否有匹配?

当我这样做的命令

csplit Shakespeare.txt '/1[56]../' '{36}'

它几乎工作,但至少有两个问题:

  1. 此输出38个文件,而不是36,编号xx00通过xx37。 (另外xx00是完全空白的。)我不明白这是怎么可能的。
  2. 其中一个文件(为什么csplit返回37个非空文件而不是我预期的36个非空文件)不是以15XX或16XX开头 - 它以“ACT 4 SCENE 15 \ n“(其中\ n应该表示换行符或换行符)。我不明白csplit如何匹配一个新的行/换行符与一个数字。

当我这样做的命令(这是我想要什么)

csplit Shakespeare.txt '/1[56][0-9][0-9]/' '{36}'

终端返回错误:csplit: 1[56][0-9][0-9]: no match加上列出所有数字将被执行上面时,它会列出。

这一点尤其没有道理给我,因为grep说,否则:

grep -c "1[56][0-9][0-9]" Shakespeare.txt
36

grep -c "1[56].." Shakespeare.txt
36

注:man csplit表明我有BSD版本从2005年1月26日起。man grep表示我从2010年7月28日起拥有BSD版本。

+0

我不明白gnu注释 - 这就是在osx上的bash:'$ bash -version'显示'GNU bash version' 3.2.57(1)-release' –

+1

是什么让你认为csplit将一个换行符当作一个号码? '/../'是要求任何两个字符,而不仅仅是数字。 – jwodder

+0

@DaveNewton在我的系统上运行这个命令,我得到:'GNU bash,版本3.2.57(1)-release(x86_64-apple-darwin15) Copyright(C)2007 Free Software Foundation,Inc.'。重点在于,在许多帮助主题上,提供了不适用于此版本BASH的解决方案。此外,这个问题更可能是BASH与之交互的命令行函数,而不是shell本身。例如,当我做'man grep'时,它在顶部显示“BSD通用命令手册”,而不是GNU或Linux。 – Chill2Macht

回答

0

根据给出的答案here by user 'DRL' on 06-20-2008,我决定尝试将-k选项添加到csplit

csplit -k Shakespeare.txt '/^1[56][0-9][0-9]/' '{36}'

此返回错误:通过xx36.txtxx37.txt)文件xx00.txt,并且每个非:csplit: ^1[56][0-9][0-9]: no match

但是,它仍然得到(更多或更少)所需的输出空文件,xx01.txt-xx36.txt具有预期的/期望的内容。 (特别是没有以“ACT 4 SCENE 15”开头的文件。

csplit手册页说,有关的-k标志如下:

-k Do not remove output files if an error occurs or a HUP, INT or TERM signal is received.

老实说,我不太明白这是什么意思,但我仍然对为什么这个解决方案工作如下猜想/工作:

猜想:csplit期望文件的开始匹配正则表达式。因此,由于该文件的起始行不符合^1[56][0-9][0-9],所以它会发起骚动并退出而没有-k标志。

尽管如此,我仍然不明白为什么1[56][0-9][0-9]没有工作,也许是相同的原因。我绝对不明白为什么1[56]..不起作用(即为什么csplit产生的第37个文件不是以模式开头)。