Комплектующие спецификации:
- являются номера строк физически присутствующие в файлах? Да
- Какая комбинация столбцов сообщает вам, что запись в File1 соответствует записи в File2? Номер строки
- Являются ли строки заголовков физически присутствующими в файлах? Нет (но мы передумаем позже)
- Являются ли данные в файлах отсортированными? Предполагается, что
- Как записываются данные в File1, но не в File2? Не указано, но, возможно, требуется третий выходной файл.
Ответ будет игнорировать проблему «удаленных записей».
Вопрос отмечает, что эта логика находит запись, вставленную в Файл2:
awk 'NR==FNR{a[$1]++;next;}!($0 in a)' file2 file1
Это близко, чтобы исправить; это должно быть !($1 in a)
. Для отправки вывода в файл требуется явная печать. Для остальной части логики, мы можем обнаружить изменения в полях довольно легко:
awk 'NR == FNR { a[$1] = $0; next }
!($1 in a) { print $0 > "ofile.1"; next }
{ split(a[$1], old);
for (i = 2; i <= NF; i++)
{
if ($i != old[i])
{
format = "%-8s %4d %d %s\n"
printf format, "File1", $1, i, $i > "ofile.2";
printf format, "File2", $1, i, old[i] > "ofile.2";
}
}
}'
Это дает разумный выход при сделанных предположениях (товарная позиция строк отсутствует). Если на самом деле заголовок строка присутствует, то вы должны захватить их и использовать их (и имена файлов тоже):
awk 'FNR == 1 { file[++num] = FILENAME; for (i = 1; i <= NF; i++) head[i] = $i; next }
NR == FNR { a[$1] = $0; next }
!($1 in a) { print $0 > "ofile.1"; next }
{ split(a[$1], old);
for (i = 2; i <= NF; i++)
{
if ($i != old[i])
{
format = "%-8s %4d %-4s %s\n"
printf format, file[1], $1, head[i], $i > "ofile.2";
printf format, file[2], $1, head[i], old[i] > "ofile.2";
}
}
}'
И чтобы получить правильные заголовки на втором выходной файл, вам необходимо сделать некоторые более незначительные корректировки:
awk 'NR == 1 { printf "%-8s %4s %-7s %s\n", "Filename", "Row", "Colname", "Colvalue" > "ofile.2" }
FNR == 1 { file[++num] = FILENAME; for (i = 1; i <= NF; i++) head[i] = $i; next }
NR == FNR { a[$1] = $0; next }
!($1 in a) { print $0 > "ofile.1"; next }
{ split(a[$1], old);
for (i = 2; i <= NF; i++)
{
if ($i != old[i])
{
format = "%-8s %4d %-7s %s\n"
printf format, file[1], $1, head[i], $i > "ofile.2";
printf format, file[2], $1, head[i], old[i] > "ofile.2";
}
}
}' File1 File2
пример вывода из этого:
OFILE.1
3 M N O P
ofile.2
Filename Row Colname Colvalue
File1 1 Col2 Z
File2 1 Col2 B
File1 2 Col3 Y
File2 2 Col3 G
Если вы хотите пустые строки после каждой записи, это тривиальная модификация - упражнение для ОП.
Должен ли быть 'File2' в последней строке вывода? Являются ли номера строк физически присутствующими в файлах? Какая комбинация столбцов говорит вам, что запись в File1 соответствует записи в File2? Это может быть только номер строки или номер строки плюс col1, или номер строки плюс col1 и col4, или только col1, или col1 и col4. Являются ли строки заголовков физически присутствующими в файлах? Являются ли данные в файлах отсортированными? –