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

Я пытаюсь извлечь редкий текст из файла, и я попробовал это:

awk 'FNR==NR {a[$0]++; next} !a[$0]' 1.txt 2.txt
http://PQR.com
http://example.com

Вот входные файлы:

File: 1.txt
http://google.com
http://GOOGLE.com
http://example1.com
http://seperate.com
http://pqr.com
File: 2.txt
http://PQR.com
http://example.com
http://google.com

Как видете, http://pqr.com доступно в файле 1.txt и http://PQR.com в 2.txt. и дисплей результата http://PQR.com, который распространен в обоих файлах. Следовательно, как я могу показать только редкий текст (не в зависимости от случаев текста)?

4
задан 6 February 2017 в 01:31

3 ответа

Так как Вы уже используете awk, использовать tolower к нижнему регистру строки:

awk 'FNR==NR {a[tolower($0)]++; next} !a[tolower($0)]' foo bar

Однако это только печатает строки в bar которые не были в foo.

Сравните:

$ sort -f bar foo | uniq -iu
http://example.com
http://example1.com
http://seperate.com

С awk, также необходимо распечатать каждую строку, которая была замечена только однажды:

$ awk '{a[tolower($0)]++} END {for (i in a) if (a[i] == 1) print i}' foo bar
http://seperate.com
http://example.com
http://example1.com
7
ответ дан 23 November 2019 в 11:37

Это - довольно простое задание для grep:

grep -viFf file2.txt file1.txt
  • -v шоу строки, которые не соответствуют
  • -i, включают нечувствительность к регистру
  • -F, делает литерал шаблонов
  • -f file1.txt шаблоны чтений для соответствия от file1.txt, линию за линией

Пример:

% cat file1.txt 
http://google.com
http://GOOGLE.com
http://example1.com
http://seperate.com
http://pqr.com

% cat file2.txt 
http://PQR.com
http://example.com
http://google.com

% grep -viFf file2.txt file1.txt
http://example1.com
http://seperate.com
4
ответ дан 23 November 2019 в 11:37

Вот решение Python с помощью эффективной реализации набора для хорошего O (n+m) производительность (с n и m быть размерами двух входных файлов).

Код

#!/usr/bin/python3
import sys

with open(sys.argv[1]) as A_file:
    A = frozenset(map(str.casefold, map(str.rstrip, A_file)))

with open(sys.argv[2]) as B_file:
    B = map(str.rstrip, B_file))
    B_minus_A = filter(lambda s: s.casefold() not in A, B)
    print(*B_minus_A, sep='\n')

Пример использования

python3 casefold-difference.py 1.txt 2.txt

Объяснение

  • Использование программы casefold поскольку сравнение строк все же возвращает строки, поскольку они появляются в 2.txt. Сворачивание случая является рекомендуемым способом сделать нечувствительное к регистру сравнение естественного языка. Если это не то, что Вы хотите (так как URL не являются на самом деле естественным языком), можно заменить его lower.

  • Если 2.txt имеет огромную сумму строк (которые не появляются в 1.txt) создание variadic списка аргументов в последнем операторе может использовать довольно большую память, и можно быть более обеспечены для замены его циклом как это:

    for item in B_minus_A:
        print(item)
    
4
ответ дан 23 November 2019 в 11:37

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

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