使用shell脚本从文件中提取特定的行号

时间:2012-08-02 14:06:03

标签: linux shell

我有一个文件,其中包含一个地址列表(ADDRESS_FILE)

0xf012134  
0xf932193  
.  
.  
0fx12923a

我有另一个文件,其中包含一个数字列表(NUMBERS_FILE)

20  
40  
.  
.  
12

我想从ADDRESS_FILE中删除前20行并将其放入新文件中 然后从ADDRESS_FILE中删除接下来的40行,等等......

我知道像下面给出的一系列sed命令可以完成工作

sed -n 1,20p ADDRESSS_FILE > temp_file_1
sed -n 20,60p ADDRESSS_FILE > temp_file_2
.  
.
sed -n somenumber,endofilep.  ADDRESS_FILE > temp_file_n

但是我想使用shell脚本自动执行此操作,这将改变每个sed执行时要删除的行数。

怎么做?

另外一般来说,linux中的文本处理命令在这种情况下非常有用吗?

4 个答案:

答案 0 :(得分:2)

假设您的行号位于名为lines的文件中,已排序等,请尝试:

#!/bin/sh

j=0
count=1
while read -r i; do
  sed -n $j,$i > filename.$count  # etc... details of sed/redirection elided
  j=$i
  count=$(($count+1))
done < lines

请注意。上面没有假设每次迭代都要分割一致的行数。

由于您还要求使用常规实用程序,请尝试split。然而,这会分成一致的行数,并且可能在这里使用有限。

答案 1 :(得分:1)

size=$(wc -l ADDRESSS_FILE)
i=1
n=1
while [ $n -lt $size ]
do
  sed -n $n,$((n+19))p ADDRESSS_FILE > temp_file_$i
  i=$((i+1))
  n=$((n+20))
done

或只是

split -l20 ADDRESSS_FILE temp_file_

(感谢Brian Agnew的想法)。

答案 2 :(得分:1)

这是一种直接从NUMBERS_FILE

读取的替代方案
n=0; i=1
while read; do 
  sed -n ${i},+$(( REPLY - 1 ))p ADDRESS_FILE > temp_file_$(( n++ ))
  (( i += REPLY ))
done < NUMBERS_FILE

答案 3 :(得分:1)

一个丑陋的解决方案适用于单个sed调用,可能会变得不那么可怕。

这会生成一个小的sed脚本来分割文件

#!/bin/bash
sum=0
count=0
sed -n -f <(while read -r n ; do
    echo $((sum+1),$((sum += n)) "w temp_file_$((count++))" ;
done < NUMBERS_FILE) ADDRESS_FILE