Копировать только Конкретный текст файла в другой

У меня есть файл abc.txt, содержимое

<classpathentry kind="src" path="Sources"/> <classpathentry kind="con" path="WOFramework/ERExtensions"/> <classpathentry kind="con" path="WOFramework/ERJars"/> <classpathentry kind="con" path="WOFramework/ERPrototypes"/> <classpathentry kind="con" path="WOFramework/JavaEOAccess"/> <classpathentry kind="con" path="WOFramework/JavaEOControl"/> <classpathentry kind="con" path="WOFramework/JavaFoundation"/> <classpathentry kind="con" path="WOFramework/JavaJDBCAdaptor"/> 

Я хочу скопировать все пути в другой файл. То есть я хочу, чтобы мой выходной текстовый файл выглядел так:

  WOFramework/ERExtensions WOFramework/ERJars WOFramework/ERPrototypes WOFramework/JavaEOAccess WOFramework/JavaEOControl WOFramework/JavaFoundation WOFramework/JavaJDBCAdaptor 

  • Почему не матч SHA?
  • sed + удалить слово из определенной строки
  • Улучшить команду sed для замены первого экземпляра символа и всех следующих символов?
  • создайте новый столбец на основе существующих столбцов, используя оператор else в awk
  • Редактируйте несколько строк из определенного раздела INI-файла
  • Нежелательное совпадение с регулярным выражением SED (эмулировать perl's. *?)
  • Печать регулярного выражения Sed в файл .txt
  • Частично удалить форматирование из текста в буфер обмена
  • 10 Solutions collect form web for “Копировать только Конкретный текст файла в другой”

    Я предполагаю, что файл следует по той же схеме. Если это так, вы можете иметь команду, как показано ниже.

     grep -o ' path=.*$' file.txt | cut -c8- |rev | cut -c 4- | rev 

    Итак, я открываю файл с помощью cat а затем извлекаю только символы из path= а затем удаляю ненужные символы с помощью cut а затем использую метод rev для удаления ненужных символов с конца.

    Другой подход awk

     awk -F'path="' '{print $2}' file.txt |rev | cut -c 4- | rev 

    Я использую path=" качестве разделителя и печатаю всю информацию после него. И rev основном делает то же, что и выше.

    тестирование

     cat file.txt <classpathentry kind="src" path="Sources"/> <classpathentry kind="con" path="WOFramework/ERExtensions"/> <classpathentry kind="con" path="WOFramework/ERJars"/> <classpathentry kind="con" path="WOFramework/ERPrototypes"/> <classpathentry kind="con" path="WOFramework/JavaEOAccess"/> <classpathentry kind="con" path="WOFramework/JavaEOControl"/> <classpathentry kind="con" path="WOFramework/JavaFoundation"/> <classpathentry kind="con" path="WOFramework/JavaJDBCAdaptor"/> 

    После выполнения команды,

     Sources WOFramework/ERExtensions WOFramework/ERJars WOFramework/ERPrototypes WOFramework/JavaEOAccess WOFramework/JavaEOControl WOFramework/JavaFoundation WOFramework/JavaJDBCAdaptor 

    Лучший подход, предложенный Стефаном в комментариях.

     cut -d '"' -f4 file.txt 

    Простой подход с awk :

     awk -F\" '/WOF/ {print $4}' abc.txt > outfile 
    • -F\" изменяет разделитель полей по умолчанию (пробел) на метку кавычки (экранируется с помощью \ )
    • /WOF/ ограничивает возвращенные результаты каждой записи (строки файла) на те, которые соответствуют шаблону: WOF
    • $4 – это четвертое поле для каждой из соответствующих записей, путь.

    Другой подход с grep и cut:

     grep "kind=\"con\"" sample.txt | cut -d \" -f 4 > sample_edited.txt 

    Это приведет к grep всем строкам, содержащим kind="con" и напечатает пути, установив разделитель cut 'to " .

     sed -n '/.*="con"[^"]*./{s///;s/..>//p}' <<\DATA <classpathentry kind="src" path="Sources"/> <classpathentry kind="con" path="WOFramework/ERExtensions"/> <classpathentry kind="con" path="WOFramework/ERJars"/> <classpathentry kind="con" path="WOFramework/ERPrototypes"/> <classpathentry kind="con" path="WOFramework/JavaEOAccess"/> <classpathentry kind="con" path="WOFramework/JavaEOControl"/> <classpathentry kind="con" path="WOFramework/JavaFoundation"/> <classpathentry kind="con" path="WOFramework/JavaJDBCAdaptor"/> DATA 

    ВЫВОД

     WOFramework/ERExtensions WOFramework/ERJars WOFramework/ERPrototypes WOFramework/JavaEOAccess WOFramework/JavaEOControl WOFramework/JavaFoundation WOFramework/JavaJDBCAdaptor 

    Думаю, это должно получить только WO …. Он также полностью переносится.

    Другое решение, если ваша версия grep поддерживает образы PCRE-стиля

     grep -oP '(?<=kind="con" path=").+?(?="/>)' abc.txt 

    С sed

     sed -e 's/.*path="//' -e 's:"/>$::' abc.txt > output_file 

    Если формат файла действительно исправлен, то подход ниже не так эффективен, как многие другие ответы, которые вы уже получили.

    Таким образом, это происходит в том случае, если формат файла изменяется или не может быть опираться (или получается, что на него нельзя полагаться после извлечения «грубой силы» и появления «путей», таких как kind= ). К сожалению, мой опыт заключается в том, что «постоянных и гарантированных» форматов просто нет. Или ненадолго.

    Сначала вы конвертируете все теги в новые строки, так что вам не нужно беспокоиться о нескольких тегах в одной строке или текстовом расположении.

     tr "<>" "\n\n" < source.txt 

    затем вы выбираете строки, содержащие одно слово «путь», за которым следуют пробелы (пробелы) и знак равенства

     | grep "\<path\\s*=" 

    из этих строк вы извлекаете компонент «путь»; таким образом, вам не нужно беспокоиться о том, что произойдет, если некоторые теги имеют атрибуты в немного другом формате

     | sed -e 's/.*path\s*=\s*"\([^"]*\)".*/\1/' # You can modify the above to handle single quotes as well as double quotes # using [\'"] instead of " 

    и, наконец, возможно, вы захотите получить каждый путь только один раз

     | sort | uniq 

    Обертывая его в одну строку,

     tr "<>" "\n\n" < source.txt | grep "\<path\\s*=" | sed -e 's/.*path\s*=\s*"\([^"]*\)".*/\1/' | sort | uniq > output.txt 

    Поскольку никто еще не опубликовал его, вот несколько решений Perl:

     perl -ne 's/.*con.*="(.+)".*/$1/ && print' file 

    объяснение

    -ne означает «Прочитать входной файл по строкам и применить скрипт, переданный -e ». s/foo/bar/ является оператором подстановки, он заменит foo на bar . В этом случае заменой будет то, что было согласовано в круглых скобках, это $1 . Регулярное выражение означает «сопоставлять все до con , затем самую длинную строку до a = и затем захватывать все между кавычками. && print напечатает измененную строку только в том случае, если замена прошла успешно.

     perl -e 'print grep{s/.*con.*=.(.+)".*/$1/}<>' file 

    объяснение

    Это немного более идиоматично. Он напечатает результат применения той же подстановки, что и выше, для каждой строки входного файла ( <> ). Просто другой способ написать один и тот же базовый подход.

     perl -F'[="]' -lane 'print $F[5] if $F[2]=~/con/' file 

    объяснение

    Параметр -a делает perl как awk , он автоматически разбивает входную строку на поля (сохраненные как @F ) на символ (символы), передаваемый параметром -F . Поскольку я скажу, что он разделен на = или " , пятое поле будет тем, за чем мы будем, и оно будет напечатано только в том случае, если второе поле соответствует con . -l добавляет новую строку для каждого вызова print (и другие вещи, которые не являются Соответствующий).


    И вот еще один grep . Это напечатает все совпадения letters/letters , оно будет корректно работать на вашем примере, но не может быть более сложным:

     grep -Eio '[az]+/[az]+' file 

    И чистая оболочка (bash / zsh / ksh):

     while IFS='=' read abc; do [[ "$b" =~ "con" ]] && a=${c/%?\/>/} && echo ${a/#?}; done < file 

    объяснение

    while read; do ... ; done < file while read; do ... ; done < file while read; do ... ; done < file цикл while read; do ... ; done < file через каждую строку файла. Установка IFS для = разбивает каждую строку на = и read abc сохраняет каждое поле в переменных $a до $c . Затем, если $b соответствует con , последние три символа удаляются из $c и результат сохраняется как $a а затем печатается с первым символом (цитатой). Подробнее см. Здесь о параметрах манипуляции с bash.

    И одно через обратную связь GNU sed,

     sed -nr 's/^.*kind=\"con\" path=\"([^"]*)\".*$/\1/p' file 

    Пример:

     $ cat aa <classpathentry kind="src" path="Sources"/> <classpathentry kind="con" path="WOFramework/ERExtensions"/> <classpathentry kind="con" path="WOFramework/ERJars"/> <classpathentry kind="con" path="WOFramework/ERPrototypes"/> <classpathentry kind="con" path="WOFramework/JavaEOAccess"/> <classpathentry kind="con" path="WOFramework/JavaEOControl"/> <classpathentry kind="con" path="WOFramework/JavaFoundation"/> <classpathentry kind="con" path="WOFramework/JavaJDBCAdaptor"/> data $ sed -nr 's/^.*kind=\"con\" path=\"([^"]*)\".*$/\1/p' aa WOFramework/ERExtensions WOFramework/ERJars WOFramework/ERPrototypes WOFramework/JavaEOAccess WOFramework/JavaEOControl WOFramework/JavaFoundation WOFramework/JavaJDBCAdaptor 

    Вы можете сделать это так:

     while IFS=\" read -r _ _ _ f4 _; do case $f4 in */*) echo "$f4";; esac done < file 
    Linux и Unix - лучшая ОС в мире.