Я пытаюсь извлечь редкий текст из файла, и я попробовал это:
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
, который распространен в обоих файлах. Следовательно, как я могу показать только редкий текст (не в зависимости от случаев текста)?
Так как Вы уже используете 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
Это - довольно простое задание для 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
Вот решение 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)