简体   繁体   中英

extracting specified line numbers from file using shell script

I have a file with a list of address it looks like this (ADDRESS_FILE)

0xf012134  
0xf932193  
.  
.  
0fx12923a

I have another file with a list of numbers it looks like this (NUMBERS_FILE)

20  
40  
.  
.  
12

I want to cut the first 20 lines from ADDRESS_FILE and put that into a new file
then cut the next 40 lines from ADDRESS_FILE so on ...

I know that a series of sed commands like the one given below does the job

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

But I want to does this automatically using shell scripting which will change the numbers of lines to cut on each sed execution.

How to do this ???

Also on a general note, which are the text processing commands in linux which are very useful in such cases?

Assuming your line numbers are in a file called lines , sorted etc., try:

#!/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

Note. The above doesn't assume a consistent number of lines to split on for each iteration.

Since you've additionally asked for a general utility, try split . However this splits on a consistent number of lines, and is perhaps of limited use here.

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

or just

split -l20 ADDRESSS_FILE temp_file_

(thanks Brian Agnew for the idea).

Here's an alternative that reads directly from the 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

An ugly solution which works with a single sed invocation, can probably be made less horrible.

This generates a tiny sed script to split the file

#!/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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM