У меня есть два файла, мне нужен выходной файл, который содержит все, чего нет в первом файле, но есть во втором файле, второй файл содержит все, что есть в первом файле, с еще некоторыми записями. Я попытался:
for j in `cat first`; do sed '/"$j"/d' second; done
cat first
a
b
c
d
e
f
# cat second
a
1
b
22
33
c
44
d
11
e
44
f
Комментарий @anubhava - отличный ответ.
С comm игнорируйте то, что уникально для первого, и игнорируйте то, что является общим
comm --nocheck-order -13 first second
Также есть простое решение аук.
ОБНОВЛЕНИЕ 1: ультра усеченная версия
mawk ' NR==FNR { __[$_] } NF -= $_ in __' FS='^$'
test_first_file.txt
test_second_file.txt
1
22
33
44
11
44
———————————————————————————————
[m/n/g]awk '
BEGIN { FS = "^$" } NR==1 {
do { __[$-_] } while ((getline)<=(FNR==NR))
} ($-_ in __)!=!___[$-_]-- ' test_first_file.txt test_second_file.txt
———————————————————————————————
1
22
33
44
11
Довольно излишне эзотерическая ИМО.
это только потому, что я не хотел, чтобы он распечатывал дубликаты. если это и nawk не беспокоят, то я мог бы обрезать его до mawk '^(FNR<NR) { __[$_] } _^($ in __)' FS='^$' test_first_file.txt test_second_file.txt
Массив __
может использовать «настоящее» имя переменной. Я никогда не видел $-_
-- что это? Вы относительно новичок в SO, вы обнаружите, что ответы «гольф» не особенно ценятся.
«_» никогда не определялся, поэтому это пустая строка — любая пустая строка оценивается как логическое значение false в awk, что означает числовой ноль, поэтому $_ — это просто $0. $-_ предназначен только для nawk, потому что он жалуется на пустое поле, поэтому $-_ просто заставляет его оценивать численно, "$-_" >>>> "$-0" >>>> $0. Вы можете сделать $+_, это то же самое. вы даже можете сделать $-OFMT или $+SUBSEP, и это даст вам 0 долларов. попробуй сам.
@glenn jackman: а чем отличается название [2]? он дает так же мало полезной информации, как __[ 2 ]
Вы должны думать о своей аудитории, когда даете ответы. Если кто-то спрашивает: «Как мне поступить (что-то, что эксперт считает очевидным)», то хвастовство кодом, выглядящим на х*й, вряд ли кому-то поможет.
@glenn jackman: и ты думаешь, что это помогает кому-то вообще, кормя их всем с ложки? если они хотят учиться, я более чем готов объяснить, но я здесь не для того, чтобы делать за них чью-то домашнюю работу
Так что минусуйте вопрос и идите дальше. Зачем вообще отвечать? Я ценю объяснение мне вопроса BTW.
Я предпочитаю ответ от @anubhava, он отлично подходит для написания сценариев. Однако, если вам просто нужна визуальная помощь, чтобы увидеть разницу между двумя файлами, старая добрая команда diff может вам очень помочь.
$ diff -y first second
a a
> 1
b b
> 22
> 33
c c
> 44
d d
> 11
e e
> 44
f f
-y или --side-by-side, вывод в два столбца.
Я тоже видел этот замечательный (полный кредит @Kent):
$ awk 'NR==FNR{a[$1]++;next;}!($0 in a)' first second
1
22
33
44
11
44
Есть еще такие команды:
Вероятно, есть много других отличных способов сделать это, это лишь некоторые из способов.
Да, это простое решение для awk.
Преобразование моего комментария в ответ, чтобы будущим посетителям было легко найти решение.
Вы можете использовать это grep
:
grep -vFxf first second
1
22
33
44
11
Варианты:
-v
: выбранные линии не соответствуют ни одному из указанных шаблонов.-F
: исправлен поиск строки-x
: точное совпадение-f
: Используйте файл для шаблоновне знал, что grep можно использовать как comm! это замечательно
Используйте
grep -vFxf first second