список шаблона, который будет удален из файла

Для иллюстрирования его далее, у нас есть два содержания файла:

file1

hello
1_hello 
2_hello
world
1_world
2_world
hello1
1_hello1
2_hello1
world1
1_world1
2_world1

file2

This
hello
1_hello
2_hello
is world
1_world
2_world
my
hello1
1_hello1
2_hello1
word
world1
1_world1
2_world1
file 

то, что я хочу, должно выполнить итерации первого столбца file1 и удалить записи, которые соответствуют в file2 и производят вывод как:

This
is
my 
word
file

Как я могу продолжить двигаться?

0
задан 20 September 2017 в 09:08

5 ответов

Вы хотите использовать awk, чтобы считать file1 и помнить все его слова. Затем считайте file2 и произведите любые слова, которые не были замечены от file1:

gawk -v RS='[[:space:]]+' 'NR==FNR {words[$1]=1; next} !($1 in words)' file1 file2

, Который использует любую последовательность пробела как разделитель записей, таким образом, каждое слово рассматривают как отдельную "строку". Это теперь GNU awk конкретный, но это - значение по умолчанию awk на Ubuntu

5
ответ дан 2 November 2019 в 05:43

Можно использовать grep -f FILE для получения шаблонов из файла FILE. В Вашем случае я рекомендую некоторые дополнительные флаги (см. объяснение ниже) для следующего финала grep вызов:

grep -v -x -F -f file1 -- file2
  • -f FILE †“Получают шаблоны от FILE, один на строку.

  • -F †“Интерпретируют шаблон как список фиксированных строк, разделенных новыми строками, любая из которых должна быть подобрана.

  • -x †“Выбирают только те соответствия, которые точно соответствуют целой строке. (Можно хотеть удалить эту опцию, если Вы хотите позволить частично согласующие отрезки длинной линии.)

  • -v †“Инвертируют смысл соответствия, для выбора несогласующих отрезков длинной линии.

<глоток> Источник: GNU grep документация или альтернативно страница руководства

Все опции, используемые выше, указаны POSIX и не требуют расширений GNU.

3
ответ дан 2 November 2019 в 05:43

Используйте grep с -v (инвертирование) флаг.

С использованием расширенного regex (-E), можно сделать | - разделенный список шаблонов, которые Вы хотите исключить, например, pattern1|pattern2|pattern3:

grep -v -E "^[0-9]|world|hello" file
0
ответ дан 2 November 2019 в 05:43

Хотя критерии удаления не очень ясны, я предполагаю, что части для удаления (www\n1_www\n2_www) для всего Word www (исправьте меня, если я неправ)

Используя (гну) sed:

sed -zr 's/(\w+)\n1_\1\n2_\1\n//g' ex
0
ответ дан 2 November 2019 в 05:43

Эта командная строка должна добиться цели:

while read -r word; do sed -e "s/\<$word\>//g" -e '/^\s*$/d' file2 -i; done < file1

После выполнения вышеупомянутой команды, выходного файла - file2 - должен посмотреть как это:

This
is
my
word
file

Больше читаемой версии вышеупомянутой командной строки:

while read -r word; do \
    sed -e "s/\<$word\>//g" -e '/^\s*$/d' file2 -i; \
done < file1

while цикл читает файл линию за линией - < file1. Значение каждой строки используется в качестве значения временной созданной переменной, названной $word - -r word. Эта переменная используется в качестве аргумента в рамках команды sed и этим заменяют [s] пустым значением в file2, первое выражение: "s/\<$word\>//g" = s/<source_value>/<replacement_value>/g. g средства флага - применяют замену ко всем соответствиям. Затем, если существует пустая строка в файле, это удалено - второе выражение: '/^\s*$/d'.

Мы должны использовать синтаксис \<...\>найти только точные совпадения. Нам нужны метки двойной кавычки - "..." - для первого выражения, потому что $word название переменной, и мы хотим к расширенному ее как ее значение в sed команда.

Опция -i средства, что изменения будут внесены в своих местах в конечном файле - file2. Если эта опция будет удалена, то результат будет брошен в stdout, но это будет не значимо. Опция -i.bak не применимо к этому сценарию, потому что конечный файл будет много раз перезаписываться, таким образом, необходимо будет создать резервную копию заранее.

1
ответ дан 2 November 2019 в 05:43

Другие вопросы по тегам:

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