Удалить строку, если другая строка начинается с текущей строки (по столбцам)

Плагинvagrant-disksizeупрощает эту задачу. Создайте виртуальную машину Debian -9 с 20-гигабайтным жестким диском.

минимально:

Vagrant.configure("2") do |config|
    config.vm.box = "debian/stretch64" 
    config.disksize.size = "20GB"
end

или, используя логику автоматической -установки плагина:

Vagrant.configure("2") do |config|

    required_plugins = %w( vagrant-vbguest vagrant-disksize )
    _retry = false
    required_plugins.each do |plugin|
        unless Vagrant.has_plugin? plugin
            system "vagrant plugin install #{plugin}"
            _retry=true
        end
    end

    if (_retry)
        exec "vagrant " + ARGV.join(' ')
    end

    config.vm.box = "debian/stretch64" 
    config.disksize.size = "20GB"
end

0
18.12.2019, 18:42
3 ответа

Это просто сортирует ввод в обратном порядке, так что «foobar» идет перед «foo», а затем не печатает текущую строку (foo )если это подстрока предыдущей (foobar )начиная с первого символа каждого.

$ sort -r file | awk 'index(prev FS,$0 FS) != 1; {prev=$0}'
h   ii  j
dddd    eeee    fe
dddd    eeee    f   g
aaaa    bbbb    xx
aaaa    bbbb    x
aaaa    bbbb    cc
aaaa    bbbb    c   dd

Если для вас важен порядок вывода, есть способы решить эту проблему, например.:

$ cat -n file | sort -k2r |
    awk '{orig=$0; $1=""} index(prev FS,$0 FS) != 1{print orig} {prev=$0}' |
    sort -n | cut -f2-
aaaa    bbbb    c   dd
aaaa    bbbb    cc
aaaa    bbbb    x
aaaa    bbbb    xx
dddd    eeee    f   g
dddd    eeee    fe
h   ii  j
1
28.01.2020, 02:39

Вы хотите удалить любую строку, которая является префиксом другой строки, на основе столбцов (полей ), а не символов. Это выполнимо с помощью awk (1 ). Сначала вы хотите отсортировать данные в обратном порядке, чтобы более длинные строки были первыми, поэтому, если строка является префиксом, она идет после строки, префиксом которой она является. Затем вы можете использовать awk для сканирования полей, чтобы увидеть, соответствуют ли они последней строке, которую вы сохранили, и если да, отбросьте ее:

sort -r input.txt | awk '
    { for (i=1; i<=NF; i++) if (save[i] != $i) {keep=1; break} }
    keep == 0 { next }
    { delete save; for (i=1; i<=NF; i++) save[i]=$i; keep=0; print }
'

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

У меня нет набора данных длиной в миллионы строк, поэтому я не уверен, что это будет хорошо для вас. Попробуйте и посмотрите.

0
28.01.2020, 02:39

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

while read l ; do if [ $(grep -c -E "^$l" tst) -eq 1 ]; then echo $l; fi ; done < tst

Однако это не удастся, если будет повторение самого длинного шаблона, поэтому вам нужно справиться с этим...

while read l ; do if [ $(grep -c -E "^$l" <<<$(sort tst | uniq)) -eq 1 ]; then echo $l; fi ; done <<<$(sort tst | uniq)
0
28.01.2020, 02:39

Теги

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