Попробуйте что-то как SystemRescueCD. Должен сделать то, в чем Вы нуждаетесь (скопируйте один жесткий диск в другого с минимальными издержками).
Кроме того, если CD/DVD-привод так же стар как остальная часть системы, Вы загружаетесь на, это, вероятно, довольно медленно, и загружающийся от CD.... будет еще медленнее. Попытайтесь установить свою спасательную систему на каком-то флеш-накопителе. Это будет намного быстрее, чем начальная загрузка с CD (это предполагает, что можно загрузиться от USB в старой системе).
awk
- это лучший инструмент для сравнения столбцов файлов. См., например, ответ на: сравните две колонки разных файлов и распечатайте, если они совпадают -- существуют похожие ответы для распечатки строк для совпадения колонок.
Поскольку необходимо распечатать строки, которые не совпадают с , мы можем создать команду awk
, которая распечатает строки в файле2, для которых в столбце 2 в файле1 было указано , а не :
$ awk 'NR==FNR{c[$2]++;next};c[$2] == 0' file1 file2
Another 193 stuff2
Another 783 stuff3
Как аналогично объяснил Тердон в вышеупомянутом вопросе,
NR==FNR
: NR - это номер текущей входной строки, а FNR - номер строки текущего файла. Эти две строки будут равны только во время чтения 1-го файла. c[$2]++; next
: если это 1-й файл, сохраните 2-е поле в массиве c
. Затем перейдите к следующей строке, чтобы она была применена только к 1-му файлу. c[$2] == 0
: оставшийся блок будет выполнен только в том случае, если это второй файл, поэтому мы проверяем, было ли уже видно поле 2 этого файла (c[$2]==0
), и если да, то выводим строку. В awk
по умолчанию выводится строка, поэтому если c[$2]==0
верно, то строка будет выведена. Но вам также нужны строки из файла 1, для которых колонка 2 не совпадает в файле 2. Это можно получить, просто обменяв их положение одной и той же командой:
$ awk 'NR==FNR{c[$2]++;next};c[$2] == 0' file2 file1
Something 456 item2
Something 768 item3
Так что теперь вы можете сгенерировать нужный вывод, используя awk
дважды. Возможно, кто-то с большим опытом работы с awk
может сделать это за один проход.
Вы пометили свой вопрос с помощью /ksh
, так что я предполагаю, что вы используете оболочку korn. В ksh
вы можете определить функцию для вашего diff, скажем diffcol2
, чтобы сделать вашу работу проще:
diffcol2()
{
awk 'NR==FNR{c[$2]++;next};c[$2] == 0' $2 $1
awk 'NR==FNR{c[$2]++;next};c[$2] == 0' $1 $2
}
У этого есть поведение, которое вы хотите:
$ diffcol2 file1 file2
Something 456 item2
Something 768 item3
Another 193 stuff2
Another 783 stuff3
Я не думаю, что diff (даже в сочетании с вырезанием) будет достаточно гибким, чтобы справиться с этим. И кажется, что на самом деле вам нужны ключи в file1, которых нет в file2, и наоборот - не строго строчный diff. Если входные файлы большие, я бы выбрал perl, но для маленьких файлов этот скрипт работает на входе при условии:
%cat a. awk
BEGIN {
while (getline < "file1") {
line=$0;
split(line,f," ");
key=f[2];
f1[key]=line
}
while (getline < "file2") {
line=$0;
split(line,f," ");
key=f[2];
f2[key]=line
}
}
END {
for (c in f1) {
if (c in f2 == 0) print f1[c]
}
for (c in f2) {
if (c in f1 == 0) print f2[c]
}
}
И это то, как вы его запускаете (обратите внимание на трюк с /dev/null, так как awk ожидает входной файл в качестве параметра:
%awk -f a.awk /dev/null
Something 456 item2
Something 768 item3
Another 193 stuff2
Another 783 stuff3