Команда sort имеет определенную поддержку для работы с огромными наборами данных, поскольку это относительно распространенный вариант использования. Огромные шаблоны grep — чрезвычайно необычный вариант использования, поэтому вы не можете надеяться, что разработчики приложили к этому много усилий.
Если порядок строк не имеет значения, вы можете отсортировать два файла, после чего их можно будет сравнить, не сохраняя в памяти более нескольких строк за раз, независимо от длины файлов. Поскольку сортировка может справиться с файлами, которые не помещаются в памяти, это эффективно.
sort originallist >originallist.sorted
sort cleaned1 | comm -23 originallist.sorted - >cleaned2.sorted
Если исходный порядок исходного списка имеет значение, вы можете добавить к нему номера строк:
nl -w 22 originallist >originallist.numbered
# then generate cleaned1 from the numbered list
Поскольку originallist.numbered
отсортирован, вы можете запустить comm
для него, чтобы обнаружить общие строки.
Если порядок имеет значение и нумеровать строки слишком поздно, можно попробовать разбить cleaned1
на куски и сделать по одному проходу в originallist
для каждого куска. С недавним расколом GNU:
cp originalfile cleaned2.in
split -l 1000000 --filter='grep -Fxv -f - cleaned2.in >cleaned2.out; mv cleaned2.out cleaned2.in' cleaned1
mv cleaned2.in cleaned2
(Обратите внимание, что F
не выполняет «совпадение полной строки», а выполняет сопоставление подстроки. Для полного совпадения строк вам также потребуется -x
.)
Наряду с использованием awk
, использование cut
намного проще. Просто определите разделитель и количество полей для анализа из
imp_2=$(printf '%s\n' "$imp_1" | cut -d_ -f4-)
printf '%s\n' "$imp_2"
Для imp_3 - imp_2
, т.е. неуникальных строк между двумя переменными, используйте утилиту comm
comm -3 <(echo "$imp_3") <(echo "$imp_2")
Ниже приведена попытка, которую я предпринял для imp1
echo $imp_1|awk -F "_" '{$1=$2=$3="";print $0}' |sed -r "s/^\s+//g"|sed -r "s/\s+$//g"|sed "s/ /_/g"
выход
Cust_support
Call_Detail
Area