Как удалить строку, соответствующую строке в массиве - PullRequest
1 голос
/ 29 мая 2020

У меня есть файл, состоящий из текста, как показано ниже

compile_tool/opt/CSDTK/bin/chipgen/Modem2G/toolpool/plugins/Calib/libcalibplugin.so
compile_tool/opt/CSDTK/bin/chipgen/Modem2G/toolpool/plugins/Calib/libcalibplugin.dill
compile_tool/opt/CSDTK/bin/lib/ruby/gems/1.8/gems/builder-2.1.2/Rakefile.pg
compile_tool/opt/mingw32_3.4.4/usr/i586-mingw32msvc/include/mmsystem.c
compile_tool/opt/mingw32_3.4.4/usr/i586-mingw32msvc/include/winnt.h
compile_tool/opt/CSDTK/bin/lib/ruby/gems/1.8/gems/builder-2.1.2/test/test_xchar.HEX

Я хочу удалить строку с расширением файла .so, .dill, .pg и .HEX. Я пробовал код ниже, но не разобрал.

#! /bin/bash
array=(.a .so .bin.ihex .dll .exe .gem .bin .png .HEX)
for a in "${array[@]}"
do 
sed -i -e "/\$a\b/d" copyright
done 

Ответы [ 4 ]

2 голосов
/ 29 мая 2020

Если ваш sed поддерживает оператор \| (or) в регулярном выражении, попробуйте:

array=(.a .so .bin.ihex .dll .exe .gem .bin .png .HEX)
pat="$(IFS='|'; echo "${array[*]}" | sed -e 's/|/\\|/g' -e 's/\./\\./g')"
sed "/\($pat\)\$/d" copyright
  • Он объединяет элементы массива и генерирует строку шаблона, которая выглядит как : \.a\|\.so\|\.bin\.ihex\|....
  • Затем строка sed "/\($pat\)\$/d" text удаляет строки, соответствующие шаблону.

Обратите внимание, что элементы вашего массива и текст "line which is having file extension .so , .dill ,.pg and .HEX" могут не совпадать. Я использовал ваш array как есть.

1 голос
/ 29 мая 2020

Вместо того, чтобы вызывать sed один раз для каждого расширения, вы можете использовать что-то вроде этого:

IFS=$'\n'
grep -F -v "${array[*]}" copyright

Если его вывод выглядит хорошо, перенаправьте его в файл и измените его имя на copyright ( и при необходимости восстановите IFS).

0 голосов
/ 29 мая 2020

То же, что предлагается @tshiono, но с использованием printf для построения шаблона

printf -v pat '\%s\|' ${array[@]}
sed "/${pat%*'\|'}/d" copyright
0 голосов
/ 29 мая 2020

Исходя из идеи, обсужденной с Огузом Исмаилом на основе его ответа:

Независимо от того, используете ли вы grep -e или sed для идентификации сохраняемых файлов, проблема в том, что в обоих случаях элементы ваши array интерпретируются как регулярное выражение. Например, у вас есть один элемент массива .a, и в качестве регулярного выражения это будет означать, что он будет соответствовать любому файлу, содержащему букву «a», кроме start имени файла. Следовательно, строка main.c также будет соответствовать шаблону .a.

Одна из возможностей - использовать сопоставление с подстановочными знаками вместо сопоставления с регулярным выражением, но это означает, что вам нужно явно l oop через ваш array: Например, чтобы проверить, будет ли строка $line удалена или должна быть сохранена, вам нужно будет сделать что-то вроде:

line_matches_pat=no
for pat in "${array[@]}"
do
  if [[ $line == *$pat ]]
  then
    line_matches_pat=yes
    break
  fi
done

Если $line_matches_pat равно yes , строка соответствует одному из шаблонов в массиве.

IMO более разумным и гибким подходом было бы хранить в array не расширения файлов, а регулярные выражения для интересующих вас файлов Это позволяет вам однажды поместить в список что-то вроде имен файлов, содержащих строку error_ и имеющих расширение .c. Когда вы это сделаете, вы можете использовать подход, аналогичный решению, предложенному @oguzismail, но, конечно, вы больше не можете использовать -F с grep:

grep -E -v "${array[*]}" copyright

Это включает расширенные регулярные выражения. Отбросьте -E, если вас устраивают простые регулярные выражения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...