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

谁知道一个Unix命令(或一系列命令)可以从文件中提取16224到16482行之间的所有行,然后将它们重定向到一个新文件中?


当前回答

在这种情况下,您可以使用sed命令,它非常快。

如前所述,让我们假设范围是:在16224和16482行之间

#get the lines from 16224 to 16482 and prints the values into filename.txt file
        sed -n '16224 ,16482p' file.txt > filename.txt 
    
#Additional Info to showcase other possible scenarios:
    
#get the 16224 th line and writes the value to filename.txt

        sed -n '16224p' file.txt > filename.txt 

#get the 16224 and 16300 line values only and write to filename.txt. 

        sed -n '16224p;16300p;' file.txt > filename.txt

其他回答

我们甚至可以在命令行检查:

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

例如:

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

使用head/tail非常简单:

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

使用sed:

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

使用awk:

awk 'NR>=16224&&NR<=16482' in.sql > out.sql

我已经为sed、perl、head+tail和我自己的awk代码编译了一些最高评级的解决方案,并通过管道关注性能,同时使用LC_ALL=C确保所有候选程序以尽可能快的速度运行,并在两者之间分配2秒的睡眠间隔。

差距是显而易见的:

   abs time    awk/app speed ratio
 ----------------------------------
   0.0672 sec :   1.00x mawk-2
   0.0839 sec :   1.25x gnu-sed
   0.1289 sec :   1.92x perl
   0.2151 sec :   3.20x gnu-head+tail

还没有机会测试这些工具的python或BSD变体。

 (fg && fg && fg && fg) 2>/dev/null; 
 echo;
 ( time ( pvE0 < "${m3t}" 
        | LC_ALL=C  mawk2 '

           BEGIN {  
                     _=10420001-(\
                    __=10420256)^(FS="^$") 
           } _<NR { 
                   print

                   if(__==NR) { exit } 
     
     }' ) | pvE9) | tee >(xxh128sum >&2) | LC_ALL=C gwc -lcm | lgp3 ; 
    sleep 2;
    (fg && fg && fg && fg) 2>/dev/null
    echo; 
    ( time ( pvE0 < "${m3t}" 
           | LC_ALL=C gsed -n '10420001,10420256p;10420256q' 
    
     ) | pvE9 ) |  tee >(xxh128sum >&2) |  LC_ALL=C gwc -lcm  | lgp3 ;
     sleep  2; (fg && fg && fg && fg) 2>/dev/null
     echo
    ( time ( pvE0 < "${m3t}" 
           | LC_ALL=C perl -ne 'print if 10420001..10420256'
    
    ) | pvE9 ) |  tee >(xxh128sum >&2) |  LC_ALL=C gwc -lcm | lgp3 ;
    sleep  2; (fg && fg && fg && fg) 2>/dev/null
    echo
    ( time ( pvE0 < "${m3t}" 
           | LC_ALL=C ghead -n +10420256 
           | LC_ALL=C gtail -n +10420001 
    ) | pvE9 ) |  tee >(xxh128sum >&2) |  LC_ALL=C gwc -lcm  | lgp3 ; 


      in0: 1.51GiB 0:00:00 [2.31GiB/s] [2.31GiB/s] [============> ] 81%            
     out9: 42.5KiB 0:00:00 [64.9KiB/s] [64.9KiB/s] [ <=> ]
( pvE 0.1 in0 < "${m3t}" | LC_ALL=C mawk2 ; )
     
   0.43s user 0.36s system 117% cpu 0.672 total
    256   43487   43487

54313365c2e66a48dc1dc33595716cc8  stdin

     out9: 42.5KiB 0:00:00 [51.7KiB/s] [51.7KiB/s] [ <=> ]
      in0: 1.51GiB 0:00:00 [1.84GiB/s] [1.84GiB/s] [==========> ] 81%            

   ( pvE 0.1 in0 < "${m3t}" |LC_ALL=C gsed -n '10420001,10420256p;10420256q'; )  
  
   0.68s user 0.34s system 121% cpu 0.839 total
    256   43487   43487

54313365c2e66a48dc1dc33595716cc8  stdin


      in0: 1.85GiB 0:00:01 [1.46GiB/s] [1.46GiB/s] [=============>] 100%            
     out9: 42.5KiB 0:00:01 [33.5KiB/s] [33.5KiB/s] [  <=> ]

( pvE 0.1 in0 < "${m3t}" | LC_ALL=C perl -ne 'print if 10420001..10420256'; )
     
   1.10s user 0.44s system 119% cpu 1.289 total
    256   43487   43487

54313365c2e66a48dc1dc33595716cc8  stdin

      in0: 1.51GiB 0:00:02 [ 728MiB/s] [ 728MiB/s] [=============> ] 81%            
     out9: 42.5KiB 0:00:02 [19.9KiB/s] [19.9KiB/s] [ <=> ]

 ( pvE 0.1 in0 < "${m3t}" 
   | LC_ALL=C ghead -n +10420256 
   | LC_ALL=C gtail -n ; )  
  
 1.98s user 1.40s system 157% cpu 2.151 total
 256   43487   43487

54313365c2e66a48dc1dc33595716cc8  stdin

那些想要计算头部、|、尾部组合的间隔的人是想多了。

下面是如何在不计算任何东西的情况下得到“16224 - 16482”范围:

cat file | head -n +16482 | tail -n +16224

解释:

The + instructs the head/tail command to "go up to / start from" (respectively) the specified line number as counted from the beginning of the file. Similarly, a - instructs them to "go up to / start from" (respectively) the specified line number as counted from the end of the file The solution shown above simply uses head first, to 'keep everything up to the top number', and then tail second, to 'keep everything from the bottom number upwards', thus defining our range of interest (with no need to compute an interval).

这可能为你工作(GNU sed):

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

或者利用bash:

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