Выберите только первые строки, содержащие повторяющуюся строку

проблема заключается в том, что окна используют другую новую строку, чем linux, поэтому при копировании ключа из окон в linux в конце строки есть \ n в конце строки, которую вы не можете видеть в linux в редакторе.

Если вы зацикливаете /var/log/auth.log и пытаетесь войти в систему, ошибка выглядит так:

sshd: error: key_read: uudecode AAAAB3N [....] == \ n

Если вы измените свой ключ на окнах, чтобы он был в одной строке без новой строки в конце и скопировал ее в linux, он должен работать (сделал трюк для меня).

1
задан 6 February 2015 в 21:47

3 ответа

Другой подход python:

читает список файлов уникальных вхождений первого списка столбцов, первое вхождение в список
#!/usr/bin/env python3
import sys
file = sys.argv[1]

with open(file) as src:
    lines = src.readlines()
for l in [[l for l in lines if l.startswith(f)][0] for f in set([l.split()[0] for l in lines])]:
    print(l, end = "")

Запустите его с текстовым файлом в качестве аргумента: [ ! d5]

python3 <script> <text_file>

Примечание

Хотя вышеприведенный вариант оказывается быстрым (проверено в файле> 1000000 строк), он может быть значительно быстрее (примерно 15% в тесты, которые я выполнил), если мы можем предположить, что строка в первом столбце не встречается на других позициях в записях (вероятно, это безопасное предположение). В этом случае мы можем пропустить функцию startswith():

#!/usr/bin/env python3
import sys
file = sys.argv[1]

with open(file) as src:
    lines = src.readlines()
for l in [[l for l in lines if f in l][0] for f in set([l.split()[0] for l in lines])]:
    print(l, end = "")
1
ответ дан 23 May 2018 в 23:28
  • 1
    Ваш подход лучше, чем мой. +1. – heemayl 7 February 2015 в 11:54
  • 2
    Я думаю, вам не нужно использовать отсортированную функцию. Op просто хочет первую линию. – Avinash Raj 7 February 2015 в 11:59
  • 3
    @heemayl Это всегда задача, чтобы сделать ее короткой :) – Jacob Vlijm 7 February 2015 в 12:10
  • 4
    @AvinashRaj абсолютно верно, удалил его. Возможно, было бы аккуратно представить первые строки , отсортированные, хотя. сортировки были отсортированы, а не общий список строк. – Jacob Vlijm 7 February 2015 в 12:11

Вы можете сделать это в следующем скрипте:

first_occurence.sh (установить его исполняемый файл)

#!/bin/bash

# Set bash to separate words by newlines only, not spaces
IFS=$'\n'
# read input
input=("$(cat)")

# get a list of unique keys - split input by space with awk for any length
unique_values=($(printf "%s\n" "${input[*]}" | awk -F' ' '{ print $1 }' | uniq))

cur=0

# check each line of input for the key
for line in ${input[@]};
do  
    # wildcard matching
    if [[ "$line" == "${unique_values[$cur]}"* ]]
    then
        # print line if match, and move on to checking the next key
        printf "%s\n" "$line"
        cur=$((cur + 1))
    fi  
    # break the loop if we have used up all of our unique keys (only duplicates remain)
    if [ $cur -ge ${#unique_values[@]} ]
    then
        break
    fi  

done

Запустить, связав файл в: [!d2 ]

./first_occurence.sh < filename 
0
ответ дан 23 May 2018 в 23:28

Я думаю, что решение steeldriver с помощью sort является лучшим, хотя, если вы хотите попробовать что-то еще, проверьте следующий скрипт Python:

#!/usr/bin/python2
import re
def checking():
        if not check_list:
            result.append(list_of_lines[index - 1])
with open('/path/to/the/file') as f:
    list_of_lines = f.readlines()
    result = []
    for index in range(1, len(list_of_lines)):
        regex_current = re.search('^[0-9]_[0-9]+', list_of_lines[index])
        regex_previous = re.search('^[0-9]_[0-9]+', list_of_lines[index - 1])
        check_list = [x for x in result if x.split()[0] == regex_previous.group()]
        if regex_current == regex_previous:
            checking()
        else:
            checking()
print ''.join(result)
0
ответ дан 23 May 2018 в 23:28

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

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