Как удалить случайную строку в текстовом файле из заданного диапазона?

Вот обновленная версия ответа Дерека Прессналла, который работает с systemd и включает предложение Элиа Кагана, просто отбросьте его в /usr/lib/systemd/system-sleep/delayed_hibernation.sh и сделайте его исполняемым:

#!/bin/bash

hibernation_timeout=1800  #30 minutes

if [ "$2" = "suspend" ]; then
    curtime=$(date +%s)
    if [ "$1" = "pre" ]; then
        echo -e "[($curtime) $@]\nExecuting pre-suspend hook..." >> /tmp/delayed_hibernation.log
        echo "$curtime" > /var/run/delayed_hibernation.lock
        rtcwake -m no -s $hibernation_timeout
    elif [ "$1" = "post" ]; then
        echo -e "[($curtime) $@]\nExecuting post-suspend hook..." >> /tmp/delayed_hibernation.log
        sustime=$(cat /var/run/delayed_hibernation.lock)
        if [ $(($curtime - $sustime)) -ge $hibernation_timeout ]; then
            echo -e "Automatic resume detected, hibernating.\n" >> /tmp/delayed_hibernation.log
            systemctl hibernate || systemctl suspend
        else
            echo -e "Manual resume detected, clearing RTC alarm.\n" >> /tmp/delayed_hibernation.log
            rtcwake -m no -s 1
        fi
        rm /var/run/delayed_hibernation.lock
    fi
fi
1
задан 30 December 2016 в 07:57

3 ответа

Чтобы удалить несколько случайных строк из определенного диапазона в текстовом файле, вот что я сделал:

Открыть файл в vim Перейти к началу диапазона, из которого вы хотите удалить несколько случайных линий. Диапазон должен содержать пустую строку внизу. Введите следующую команду:
.,/^\s*$/-1 !sed -e $((9 * $RANDOM / 32267))d

. - Отсюда

, / ^ \ s * $ / - 1 - до последней непустой строки

! Sed -e $ ((9 * $ RANDOM / 32267)) d - команда sed для удаления случайной строки

Это приведет к случайному удалению одной строки.

Теперь, если вы хотите удалить еще 5 случайных строк, просто сделайте 5 @: и vim делает все остальное.

Это может быть дополнительно улучшено, если я могу заменить это 9 (количество строк, из которых нужно удалить) с некоторым выражением, которое будет универсальным

1
ответ дан 25 May 2018 в 08:43
  • 1
    bash только выполняет целочисленную математику, поэтому $((9 * RANDOM / 32267)) приведет только к 0 или 9. Вам действительно нужно по модулю. [F2] – geirha 14 July 2012 в 15:02
  • 2
    Вот awk, который читает ввод в массив, затем печатает все, кроме одной случайной строки из массива. [F1] – geirha 14 July 2012 в 16:15
  • 3
    @geirha Спасибо! Я по-прежнему буду использовать ту же технику 4 @: для удаления нескольких строк в vim. Но мне интересно, как я могу напечатать все, кроме «n» случайных строк, используя awk – deshmukh 15 July 2012 в 11:02
  • 4
    Это немного сложнее, так как теперь вам нужно отслеживать, какие строки вы уже пропустили. Вместо того, чтобы сделать r int, мы сделаем его массивом и заполним его случайными числами, пока не будет n уникальных. awk '{a[NR]=$0}END{srand();r[int(NR*rand())+1];while(length(r)<(n<NR?n:NR))r[int(NR*rand())+1];for(i=1;i<=NR;++i)if(\!(i in r))print a[i]}' n=2 n = 2 в конце говорит опустить две строки. – geirha 15 July 2012 в 13:08
  • 5
    Ах, извините, я забыл, что функция mawk length () работает только с строками, а не с массивами. Я только тестировал его с gawk. Есть опция gawk (GNU awk)? – geirha 23 July 2012 в 20:26

Используйте следующую команду

:nd

, где n - номер строки.

0
ответ дан 25 May 2018 в 08:43
  • 1
    Это просто удалит определенную строку. Я хочу удалить случайную строку. – deshmukh 13 July 2012 в 10:47

Возможно также с python:

bash-4.3$ python -c 'import sys,random;lines=sys.stdin.readlines();lines.pop(random.randint(0,len(lines)-1));print "".join(lines)' < input.txt
Line 1: abcd
Line 2: efgh
Line 3: ijkl
Line 5: qrst
Line 6: uvwxyz

Процесс здесь прост, мы перенаправляем входной файл в файл stdin python и читаем все строки в список. Затем мы выбираем случайный индекс строки через функцию random.randint() в пределах диапазона всех индексов в списке, от индекса от 0 до последнего индекса (это то, что делает len(lines)-1). Этот индекс удаляется из списка через lines.pop(), и затем мы печатаем повторно собранный текст. Довольно просто

0
ответ дан 25 May 2018 в 08:43

Другие вопросы по тегам:

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