Выберите строки из текстового файла, которым перечислили идентификаторы в другом файле

../ нотация для "родительского каталога" так, в случае Вы представили:

/usr/local/bin/../../etc/yarbu/conf/default

Система разрешит что как:

/usr/etc/yarbu/conf/default

Это - то же, как будто Вы были в каталоге /usr/local/bin и Вы затем ввели cd .. дважды, Вы теперь были бы в /usr каталог.

Можно проверить это сами:

$ cd /usr/local/bin
$ pwd
/usr/local/bin
$ cd /usr/local/bin/../../../
$ pwd
/
13
23.05.2017, 15:40
4 ответа

Я предполагаю, что Вы имели в виду grep -f нет grep -F но Вам на самом деле нужна комбинация обоих и -w:

grep -Fwf ids.csv table.csv

Причина Вы получали ложные положительные стороны, (я предполагаю, Вы не объяснили), потому что, если идентификатор может содержаться в другом, то оба будут распечатаны. -w удаляет эту проблему и -F удостоверяется, что Ваши шаблоны рассматривают как строки, не регулярные выражения. От man grep:

   -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.)
   -w, --word-regexp
          Select  only  those  lines  containing  matches  that form whole
          words.  The test is that the matching substring must  either  be
          at  the  beginning  of  the  line,  or  preceded  by  a non-word
          constituent character.  Similarly, it must be either at the  end
          of  the  line  or  followed by a non-word constituent character.
          Word-constituent  characters  are  letters,  digits,   and   the
          underscore.

   -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.)

Если Ваши ложные положительные стороны - то, потому что идентификатор может присутствовать в неидентификационном поле, цикле через Ваш файл вместо этого:

while read pat; do grep -w "^$pat" table.csv; done < ids.csv

или, быстрее:

xargs -I {} grep "^{}" table.csv < ids.csv

Лично, я выполнил бы в этом perl хотя:

perl -lane 'BEGIN{open(A,"ids.csv"); while(<A>){chomp; $k{$_}++}} 
            print $_ if defined($k{$F[0]}); ' table.csv
19
27.01.2020, 19:52
  • 1
    +1, Но: Что, если существуют потенциальные ложные положительные стороны, которые соответствуют идентификатору, точно мудрому словом, просто не в идентификационном столбце? Если Вы не можете использовать ^ с-F Вы не можете быть нацелены на первый столбец конкретно. –  goldilocks 23.01.2014, 22:14
  • 2
    @goldilocks, если они соответствуют точно, они не ложные положительные стороны. Я получаю то, что Вы имеете в виду, но в этом случае, OP должен показать их входные файлы. –  terdon♦ 23.01.2014, 22:15
  • 3
    ^id\t бит от OP подразумевает id мог бы произойти в другом столбце. В противном случае это не имеет значения. –  goldilocks 23.01.2014, 22:17
  • 4
    @goldilocks, ответ отредактирован. –  terdon♦ 23.01.2014, 22:25
  • 5
    Путем мы раньше делали, это должно было создать временные файлы (использующий awk или sed), который добавил, уникальный символ (скажите, управление-A), разграничивание поля, которое мы хотели искать, затем использовать grep-F-f temppatternfile temptargetfile | TR-d '\001' –  Mark Plotnick 24.01.2014, 01:14

join утилита - то, что Вы хотите. Это действительно требует, чтобы входные файлы были лексически отсортированы.

Принятие Вашей оболочки является ударом или ksh:

join -t $'\t' <(sort ids.csv) <(sort table.csv)

Не будучи должен отсортировать, обычное awk решение

awk -F '\t' 'NR==FNR {id[$1]; next} $1 in id' ids.csv table.csv
7
27.01.2020, 19:52
  • 1
    Когда я попробовал, но в конечном счете не удался передать, присоединиться, клудж. Не работает на меня так хорошо. –  alamar 24.01.2014, 00:55
  • 2
    join не клудж: Ваши слова были Вами, не мог понять это. Откройте свой ум и учитесь. То, что производит Вас, добиралось, и как это отличается от того, что Вы ожидаете? –  glenn jackman 24.01.2014, 02:12
  • 3
    +1, это - задание для join. –  don_crissti 01.05.2015, 03:46

Можно также использовать рубин, чтобы сделать что-то подобное:

ruby -pe 'File.open("id.csv").each { |i| puts i if i =~ /\$\_/ }' table.csv
0
27.01.2020, 19:52

Ответы на этот SO-вопрос помогли мне обойти трудности с соединением. По сути, когда вы сортируете файл при подготовке к отправке для присоединения, вам нужно убедиться, что вы сортируете на основе столбца, к которому присоединяетесь. Поэтому, если это первое, вам нужно указать, какой символ-разделитель находится в файле и что вы хотите, чтобы он сортировался по первому полю (и только по первому полю ). В противном случае, если первое поле имеет переменную ширину (, например ), ваши разделители и, возможно, другие поля могут начать влиять на порядок сортировки.

Таким образом, используйте опцию -t сортировки, чтобы указать символ-разделитель, и используйте опцию -k, чтобы указать поле (, помня, что вам нужно начальное и конечное поля -, даже если они тот же -или он будет сортироваться от этого символа до конца строки ).

Таким образом, для файла, разделенного вкладкой -, как в этом вопросе, следующее должно работать (благодаря ответу Гленна для структуры):

join -t$'\t' <(sort -d ids.csv) <(sort -d -t$'\t' -k1,1 table.csv) > output.csv

(Для справки, -флаг d означает сортировку по словарю. Вы также можете использовать флаг -b для игнорирования начальных пробелов, см. man sortиman join).

В качестве более общего примера предположим, что вы соединяете два файла -, разделенных запятыми,-input1.csvв третьем столбце и input2.csvв четвертом.Вы можете использовать

join -t, -1 3 -2 4 <(sort -d -t, -k3,3 input2.csv) <(sort -d -t, -k4,4 input2.csv) > output.csv

Здесь параметры -1и -2указывают, какие поля объединять в первом и втором входных файлах соответственно.

2
27.01.2020, 19:52

Теги

Похожие вопросы