如何从Unix上的文本文件中提取预定范围的行?

我有一个〜23000行的SQL转储,包含几个数据库值的数据。 我需要提取该文件的某个部分(即单个数据库的数据),并将其放在一个新文件中。 我知道我想要的数据的开始和结束行号。

有没有人知道一个Unix命令(或一系列命令)提取行16224和16482之间的文件中的所有行,然后redirect到一个新的文件?

sed -n 16224,16482p filename > newfile 

从sed手册 :

p – 打印模式空间(到标准输出)。 此命令通常仅与-n命令行选项结合使用。

n – 如果自动打印未禁用,则打印模式空间,然后不pipe用下一行inputreplace模式空间。 如果没有更多的input,那么sed退出而不处理任何更多的命令。

一个sed脚本中的地址可以是以下任何一种forms:

数字指定一个行号只会匹配input中的那一行。

地址范围可以通过指定由逗号(,)分隔的两个地址来指定。 地址范围匹配从第一个地址匹配的地方开始的行,直到第二个地址匹配(包含)。

 sed -n '16224,16482 p' orig-data-file > new-file 

其中16224,16482是起始行号码和结束行号码,包括在内。 这是1索引。 -n抑制回显input作为输出,你显然不想要; 数字表示使下列命令操作的行的范围; 命令p打印出相关的行。

非常简单的使用头部/尾部:

 head -16482 in.sql | tail -258 > out.sql 

使用sed:

 sed -n '16482,16482p' in.sql > out.sql 

使用awk:

 awk 'NR>=10&&NR<=20' in.sql > out.sql 

awk还有另一种方法:

 awk 'NR==16224, NR==16482' file 

如果文件很大,在读完最后一行之后exit可能会很好。 这样就不会不必要地读取文件,直到最后:

 awk 'NR==16224, NR==16482-1; NR==16482 {print; exit}' file 

你可以使用'vi',然后使用下面的命令:

 :16224,16482w!/tmp/some-file 

或者:

 cat file | head -n 16482 | tail -n 258 

编辑: – 只要添加解释,您使用头-n 16482显示第一个16482线,然后使用尾-n 258来获得第一个输出的最后258行。

 perl -ne 'print if 16224..16482' file.txt > new_file.txt 
  # print section of file based on line numbers sed -n '16224 ,16482p' # method 1 sed '16224,16482!d' # method 2 

sed -n '16224,16482p' < dump.sql

 cat dump.txt | head -16224 | tail -258 

应该做的伎俩。 这种方法的缺点是你需要做算术来确定tail的参数,并考虑你是否希望“between”包含结束行。

快速和肮脏:

 head -16428 < file.in | tail -259 > file.out 

可能不是最好的办法,但它应该工作。

BTW:259 = 16482-16224 + 1。

我正要发布头部/尾部的技巧,但实际上我可能只是启动emacs。 😉

  1. escx goto-line ret 16224
  2. 标记( ctrl空格
  3. escx goto-line ret 16482
  4. escw

打开新的输出文件,ctl -y保存

让我看看发生了什么。

我会用:

 awk 'FNR >= 16224 && FNR <= 16482' my_file > extracted.txt 

FNR包含从文件读取的行的logging(行)号码。

我写了一个名为splitter的Haskell程序,完成这个工作: 阅读我发布的博客文章 。

您可以使用该程序如下:

 $ cat somefile | splitter 16224-16482 

这就是这一切。 你将需要Haskell来安装它。 只是:

 $ cabal install splitter 

你完成了。 我希望你觉得这个程序有用。

即使我们可以这样做,检查命令行:

 cat filename|sed 'n1,n2!d' > abc.txt 

例如:

 cat foo.pl|sed '100,200!d' > abc.txt 

使用ruby:

 ruby -ne 'puts "#{$.}: #{$_}" if $. >= 32613500 && $. <= 32614500' < GND.rdf > GND.extract.rdf 

我写了一个小的bash脚本,你可以从命令行运行,只要你更新你的PATH来包含它的目录(或者你可以把它放在一个已经包含在PATH中的目录中)。

用法:$ pinch filename start-line end-line

 #!/bin/bash # Display line number ranges of a file to the terminal. # Usage: $ pinch filename start-line end-line # By Evan J. Coon FILENAME=$1 START=$2 END=$3 ERROR="[PINCH ERROR]" # Check that the number of arguments is 3 if [ $# -lt 3 ]; then echo "$ERROR Need three arguments: Filename Start-line End-line" exit 1 fi # Check that the file exists. if [ ! -f "$FILENAME" ]; then echo -e "$ERROR File does not exist. \n\t$FILENAME" exit 1 fi # Check that start-line is not greater than end-line if [ "$START" -gt "$END" ]; then echo -e "$ERROR Start line is greater than End line." exit 1 fi # Check that start-line is positive. if [ "$START" -lt 0 ]; then echo -e "$ERROR Start line is less than 0." exit 1 fi # Check that end-line is positive. if [ "$END" -lt 0 ]; then echo -e "$ERROR End line is less than 0." exit 1 fi NUMOFLINES=$(wc -l < "$FILENAME") # Check that end-line is not greater than the number of lines in the file. if [ "$END" -gt "$NUMOFLINES" ]; then echo -e "$ERROR End line is greater than number of lines in file." exit 1 fi # The distance from the end of the file to end-line ENDDIFF=$(( NUMOFLINES - END )) # For larger files, this will run more quickly. If the distance from the # end of the file to the end-line is less than the distance from the # start of the file to the start-line, then start pinching from the # bottom as opposed to the top. if [ "$START" -lt "$ENDDIFF" ]; then < "$FILENAME" head -n $END | tail -n +$START else < "$FILENAME" tail -n +$START | head -n $(( END-START+1 )) fi # Success exit 0 

这可能适用于你(GNU sed):

 sed -ne '16224,16482w newfile' -e '16482q' file 

或者利用bash:

 sed -n $'16224,16482w newfile\n16482q' file 

-n在接受答案的工作。 如果你倾向于另一种方式。

 cat $filename | sed "${linenum}p;d"; 

这样做如下:

  1. 在一个文件的内容pipe道(或饲料文本,但是你想要的)。
  2. sedselect给定的行,打印它
  3. d需要删除行,否则sed将假定所有的行最终都会被打印。 即没有d,您将获得所选行打印的所有行两次,因为您有$ {linenum} p部分要求打印。 我很确定-n在这里基本上和d一样。

我想从一个脚本使用一个variables来做同样的事情,并通过在$variables周围加引号将variables名与p:

 sed -n "$first","$count"p imagelist.txt >"$imageblock" 

我想把一个列表分成不同的文件夹,find最初的问题,并回答一个有用的步骤。 (拆分命令不是旧的操作系统上的选项,我必须将代码移植到)。

我认为这可能是有用的解决scheme。 如果表名是“person”,则可以使用sed来获取恢复表所需的所有行。

 sed -n -e '/DROP TABLE IF EXISTS.*`person `/,/UNLOCK TABLES/p' data.sql > new_data.sql 

根据这个答案 ,在缺less正在还原的表的“DROP TABLE IF EXIST”的情况下,在使用它来防止删除下一个表之前,需要删除新文件底部的几行。

详细信息也可以在这里find