Как выбрать определенные строки (n, n+4, n+8, n+12...) из файла?

Microsoft представила новую настройку под названием fastboot в Windows 8 (Я полагаю ), которая ускоряет процесс загрузки Windows. Из-за этого альтернативные загрузчики не запускаются.

Быстрая загрузка не может быть отключена в BIOS, но должна быть отключена в Windows. Вы можете найти эту опцию в одном из диалогов настроек энергии.

С UEFI не должно возникнуть проблем, если вы придерживаетесь более новых руководств по настройке Grub. Старый метод MBR больше не следует использовать.

11
09.05.2019, 10:34
8 ответов

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

awk '!((NR - 1) % 4)' input > output

Выяснение того, как это работает, остается читателю в качестве упражнения.

29
27.01.2020, 19:56

Звоните сscriptname filename skip(4 в вашем случае )Он работает, вытягивая iterстрок из верхней части файла, а затем выводя только последние. Затем он увеличивает iterна skipsи повторяет до тех пор, пока значение iterне превышает linesв file.

#!/bin/bash
file="$1"
lines=`wc -l < "$file"`
skips="$2" || "4"
iter=1
while [ "$iter" -le "$lines" ]; do
 head "$file" -n $iter | tail -n 1
 iter=$(( $iter + $skips ))
done
1
27.01.2020, 19:56

С GNUsed:

sed '1~4!d' < input > output

Со стандартнымsed:

sed -n 'p;n;n;n' < input > output

С 1и 4в переменных $nи $i:

sed "$n~$i!d" # GNU only
awk -v n="$n" -v i="$i" 'NR >= n && (NR % i) == (n % i)'
22
27.01.2020, 19:56

Добавление обязательного решения perl:

perl -ne 'print if $. % 4 == 1' input > output
7
27.01.2020, 19:56

Использованиеsplit(GNU coreutils):

split -nr/1/4 input > output
  • -nгенерировать CHUNKSвыходные файлы

и CHUNKSкак

  • r/K/Nиспользовать циклическое распределение и выводить только Kth из N в стандартный вывод без разделения строк/записей
23
27.01.2020, 19:56

Версия Python, просто для удовольствия:

with open('input.txt') as f:
    for i, line in enumerate(f.readlines()):
        if i%4 == 0:
            print(line.strip())
4
27.01.2020, 19:56

POSIX sed:Этот метод использует posixly sed, поэтому его можно запускать везде или, по крайней мере, те sed, которые уважают posix.

 $ sed -ne '
   /\n/!{
    H;s/.*//;x
   }

   :loop
       $bdone
       N;s/\n/&/4
       tdone
   bloop

   :done
   s/.//;P
 ' input.file

Другим является программная генерация кода sed для целей масштабируемости:

$ code=$(yes n | head -n 4 | paste -sd\; | sed s/n/p/)
$ sed -ne "$code" input.file

Perl:мы заполняем -массив A до размера 4. Затем мы печатаем его первый элемент, а также очищаем массив.

$ perl -pe '
   $A[@A] = @A ? <> : $_ while @A < 4;
   $_ = (splice @A)[0];
' input.file
3
27.01.2020, 19:56

Чистый Баш:

mapfile -t lines < input
for (( i=0; i < ${#lines[@]}; i+=4 ))
do printf "%s\n" "${lines[$i]}"
done

mapfile — это встроенная функция, добавленная в Bash 4, которая считывает стандартный ввод в массив, названный здесь lines, с одной строкой на запись. Опция -tудаляет последние символы новой строки.

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

mapfile -t -c4 -C 'printf "%.0s%s\n"' < input

Здесь используется встроенная функция printf; код формата %.0sподавляет первый аргумент (индекс ), поэтому печатается только строка.

Вы можете использовать ту же команду для печати каждой четвертой строки, начиная со строки 1, 2 или 3, но вам придется добавить 3, 2 или 1 строку к input, прежде чем передать ее в mapfile. что, я думаю, доставляет больше хлопот, чем того стоит.

Это тоже работает:

mapfile -t lines < input
printf "%s%.0s%.0s%.0s\n" "${lines[@]}"

Здесь printfпотребляет четыре элемента массива linesза раз, печатая только первый и пропуская остальные три с помощью %.0s. Мне это не нравится, так как вам нужно вручную возиться со строкой формата для разных интервалов или начальных точек.

1
27.01.2020, 19:56

Теги

Похожие вопросы