2

Как мне извлечь содержимое файла из другого файла

Скажем, у меня есть файл "file1", и он имеет

a
b
c

и другой файл "file2", который имеет

a
b
c
d
e
f

Я бы обычно делал

cat file2 | grep -v a | grep -v b | grep -v c 

Есть ли способ сделать это с файлами

grep -v file2 file1

2 ответа2

5

Используйте diff чтобы найти различия, и sed чтобы выбрать, отформатировать и напечатать только добавленные строки:

diff file1 file2 | sed -n "/^>/{s/> //;p}"

Добавлено:

Если файлы расположены в разных порядках, то сначала sort их оба, а затем diff их.

sort file1 > file1.s
sort file2 > file2.s
diff file1.s file2.s | sed -n "/^>/{s/> //;p}"

Если вы используете bash , вы можете использовать <(...) подстановку процесса:

diff <(sort file1) <(sort file2) | sed -n "/^>/{s/> //;p}"
2

GNU grep (и я думаю, что и другие) может использовать опцию -f :

   -f FILE, --file=FILE
          Obtain patterns from FILE, one  per  line.   The  empty
          file  contains  zero  patterns,  and  therefore matches
          nothing.  (-f is specified by POSIX.)

Итак, вы можете сделать это:

grep -vFf file1 file2 

Следуя предложению Николь Гамильтон в комментариях, я добавил опцию '-F', которая заставляет grep интерпретировать свой PATTERN (в данном случае каждую строку в file1) как фиксированные строки, а не регулярные выражения:

  -F, --fixed-strings
          Interpret PATTERN as  a  list  of  fixed  strings,  separated  by
          newlines,  any  of  which  is to be matched.  (-F is specified by
          POSIX.)

Я также написал сценарий PERL с еще несколькими опциями:

$ list_compare.pl -h

  USAGE: compare_lists.pl FILE1 FILE2

  This script will compare FILE1 and FILE2, searching for the 
  contents of FILE1 in FILE2 (and NOT vice-versa). FILE one must 
  be one search pattern per line, the search pattern need only be 
  contained within one of the lines of FILE2.

OPTIONS: 
  -c : Print patterns COMMON to both files
  -f : Search only the first characters (until the 1st space) of each line of 
       FILE2 for the search pattern given in FILE1. So, if FILE1 contains
       "foo bar", only "foo" will be taken as a pattern (MUCH faster).
  -d : Print duplicate entries     
  -m : Print patterns MISSING in FILE2 (default)
  -h : Print this help and exit

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .