2012-03-27 3 views
22

Рассмотрим текстовый файл с научными данными и т.д .:Как удалить каждую X-ю строку в текстовом файле?

5.787037037037037063e-02 2.048402977658663748e-01 
1.157407407407407413e-01 4.021264347118673754e-01 
1.736111111111111049e-01 5.782032163406526371e-01 

Как можно легко удалить, например, каждую вторую линию, или каждый 9 из 10 строк в файле? Возможно ли это, например, с помощью сценария bash?

Фон: файл очень большой, но мне нужно гораздо меньше данных для построения. Обратите внимание, что я использую Ubuntu/Linux.

+0

Вы уверены, что вы хотите указать, выборку данных, как это? Может быть, лучше выполнить понижающую дискретизацию, где данные из групп из N строк усредняются каким-либо соответствующим образом. Точечная выборка потенциально приводит к проблемам с псевдонимом. – Kaz

+0

http: //unix.stackexchange.com/questions/168004/delete-every-nth-line-in-shell –

ответ

53

Это легко сделать с AWK.

Удалите все остальные строки:

awk 'NR % 2 == 0' file > newfile 

Удалить все 10 строку:

awk 'NR % 10 != 0' file > newfile 

Переменная NR в AWK номер строки. Все, что находится вне {} в awk, является условным, а действие по умолчанию - печать.

+0

Никогда не слышал о awk раньше. Обязательно проверьте это сейчас! Благодаря! – Ingo

+0

Awk очень хорош для обработки текста в сценариях оболочки. Он также может выполнять математику с плавающей запятой, которую bash не может сделать. Определенно стоит потратить время на изучение кодировщиков оболочки. – jordanm

+1

Первая команда оставляет строки с четными идентификаторами на месте, она не удаляет их. Если вы хотите удалить его, используйте awk 'NR% 2! = 0' file> newfile. – Olga

2

Try что-то вроде:

awk 'NR%3==0{print $0}' file 

Это напечатает одну строку в три. Или:

awk 'NR%10<9{print $0}' file 

будет печатать 9 линий из десяти.

+1

Печать - это действие по умолчанию, поэтому 'print $ 0' не требуется. – jordanm

+0

Я знаю. Мне кажется слишком странным. (Я не опытный пользователь awk.) – Mat

+0

NR% 10 никогда не может быть больше 9 ... – 123

2

Вы можете сделать это с помощью sed, например.

sed -n -e 'p;N;d;' file # print every other line, starting with line 1 

Если у вас есть GNU СЭД это довольно легко

sed -n -e '0~10p' file # print every 10th line 
sed -n -e '1~2p' file # print every other line starting with line 1 
sed -n -e '0~2p' file # print every other line starting with line 2 
0

Вы можете использовать скрипт awk и shell. Awk может быть трудно, но ...

Это удалит конкретные строки, которые вы сказать ему:

nawk -f awkfile.awk [filename] 

awkfile.awk contents 

BEGIN { 
if (!lines) lines="3 4 7 8" 
n=split(lines, lA, FS) 
for(i=1;i<=n;i++) 
linesA[lA[i]] 
} 
!(FNR in linesA) 

Кроме того, я не могу вспомнить, если ВИМ поставляется со стандартной Ubuntu или нет. Если не получишь.

Затем откройте файл с ВИМ Vim [имя файла]

Затем введите

:%!awk NR\%2 or :%!awk NR\%2 

Это приведет к удалению каждой другой строки. Просто измените 2 на другое целое число на другую частоту.

6

Как насчет perl?

perl -n -e '$.%10==0&&print'  # print every 10th line 
+0

Он хочет удалить каждую 10-ю строчку, а не держать каждую 10-ю строку. Просто измените свой код,! = Вместо ==. – jordanm

+2

Нет. Он заявляет: «Как я могу легко ** удалить **, например, каждую вторую строку или ** каждые 9 из 10 ** строк в файле?», Удаление каждых 9 из 10 строк означает печать каждого десятый. Как вы говорите, после того, как решение опубликовано, его легко адаптировать, поэтому я не потрудился исправить другого плаката, который сделал ту же ошибку. – Sorpigal

+0

Перечитав вопрос снова, я считаю, что ваша интерпретация верна. – jordanm

2

Это может работать для вас (GNU СЭД):

seq 10 | sed '0~2d' # delete every 2nd line 
1 
3 
5 
7 
9 
seq 100 | sed '0~10!d' # delete 9 out of 10 lines 
10 
20 
30 
40 
50 
60 
70 
80 
90 
100 
Смежные вопросы