2015-04-18 2 views
4

У меня есть большой файл с 1000 строк. Мне нужно получить 110 строк от него. Строки должны быть равномерно распределены во входном файле.Получите n строк из файла, равных разнесенных

Например, я прочитал 4 строки из файла с 10 строками

Input File

 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 

Outfile:

 
1 
4 
7 
10 

ответ

4

Использование:

sed -n '1~9p' < file 

-n оп прекратит вывод sed. '1~9p' сообщает sed для печати из строки 1 каждые 9 строк (p в конце заказов sed для печати).

Чтобы приблизиться к 110 линиям, вам необходимо распечатать каждую 9-ю строку (1000/110 ~ 9).


Update: Этот ответ будет печатать 112 строк, если вам нужно ровно 110 строк, вы можете ограничить вывод только с помощью head так:

sed -n '1~9p' < file | head -n 110 
+0

Это печать первые 9 строк. – abilng

+0

Это была опечатка (дополнительная ','), фиксированная – higuaro

+1

int (1000/9) = 111, а не 110. –

2

С AWK вы можете сделать:

awk -v interval=3 '(NR-1)%interval==0' file 

где интервал - это разница в количестве строк между последовательными строками, которые печатаются. Значение представляет собой, по существу, деление всех строк в файле, деленное на количество напечатанных строк.

3
$ cat tst.awk 
NR==FNR { next } 
FNR==1 { mod = int((NR-1)/tgt) } 
!((FNR-1)%mod) { print; cnt++ } 
cnt == tgt { exit } 

$ wc -l file1 
1000 file1 

$ awk -v tgt=110 -f tst.awk file1 file1 > file2 

$ wc -l file2 
110 file2 

$ head -5 file2 
1 
10 
19 
28 
37 

$ tail -5 file2 
946 
955 
964 
973 
982 

Обратите внимание, что это не будет производить вывод, который вы размещены в вашем вопросе данного ваш размещен входной файл, так как это потребовало бы алгоритм, который не всегда используют один и тот же интервал между выходными линиями. Вы можете динамически вычислять mod и корректировать его при анализе входного файла, если хотите, но приведенное выше может быть достаточно хорошим.

2

Я часто люблю использовать сочетание оболочки и AWK для такого рода вещей

#!/bin/bash 

filename=$1 
toprint=$2 

awk -v tot=$(expr $(wc -l < $filename)) -v toprint=$toprint ' 
BEGIN{ interval=int((tot-1)/(toprint-1)) } 

(NR-1)%interval==0 { 
    print; 
    nbr++ 
} 

nbr==toprint{exit} 

' $filename 

Некоторые примеры:

$./spread.sh 1001lines 5 
1 
251 
501 
751 
1001 
$ ./spread.sh 1000lines 110 |head -n 3 
1 
10 
19 
$ ./spread.sh 1000lines 110 |tail -n 3 
964 
973 
982 
Смежные вопросы