Разбейте строки на строки, отсортируйте и удалите их и используйте comm
для анализа.(См. BashFAQ # 36 ).
Предположим, на примере, что вы хотите сравнить директивы LoadModule
между двумя файлами конфигурации Apache.
file1:
...other stuff...
LoadModule foo modules/foo.so
LoadModule bar modules/bar.so
LoadModule baz modules/baz.so
...other stuff...
file2:
...other stuff...
LoadModule foo modules/foo.so
...other stuff...
Итак, для этого:
comm -2 -3 \
<(gawk '/LoadModule/ { print $2 }' file1 | sort -u)
<(gawk '/LoadModule/ { print $2 }' file2 | sort -u)
... будет подавлять любые строки, найденные в обоихили только в более коротком файле, и дать вам имена модулей, найденные в третьем, что дает следующий вывод:
bar
baz
Для тех, кто рассматривает этот вопрос, имея в виду более интересные варианты использования - к сожалению, покаФлаг -z
сортировки GNU может обрабатывать разделители NUL (для сравнения строк, содержащих новые строки), comm
не может.Однако вы можете написать свою собственную реализацию comm
в оболочке, которая поддерживает разделители NUL, например, в следующем примере:
#!/bin/bash
exec 3<"$1" 4<"$2"
IFS='' read -u 4 -d ''; input_two="$REPLY"
while IFS='' read -u 3 -d '' ; do
input_one="$REPLY"
while [[ $input_two < $input_one ]] ; do
IFS='' read -u 4 -d '' || exit 0
input_two="$REPLY"
done
if [[ $input_two = "$input_one" ]] ; then
printf '%s\0' "$input_two"
fi
done