2015-11-18 3 views
0

Примечание. Это задание, а не прямой ответ, пожалуйста, укажите мне в правильном направлении.Зачистка всего содержимого за пределами <body> &</body> теги (и те теги сами)

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

Моя проблема: я не могу на всю жизнь уйти от тегов тела. Смотрите мой бод ниже.

directory=$1 
files=$(du -a $directory | find -name "*.html") 
for f in $files; do 
    file=$f 
    outputdata=$(sed -n "/body/,/body/p" $file) 
    echo $outputdata 
done 

Любой совет?

+2

... 'du -a'? Почему в ...? –

+2

Является ли задание специально просить вас иметь дело с HTML из оболочки, или это просто плохо разработанное назначение, которое предполагает, что стандартные инструменты оболочки, такие как 'sed', подходят для обработки HTML? – chepner

+0

Кроме того, это неправильный способ получить список имен файлов. См. Первую запись в http://mywiki.wooledge.org/BashPitfalls (ее заголовок говорит о 'ls', но в тексте также рассматривается« find »). –

ответ

1

Я понимаю, что вы не хотите ответа, но есть конфликт врожденный, направляющий кого-то к полностью правильному ответу, предоставляя только намеки (которые по своей природе легко ошибаются).

while IFS= read -r -d '' filename; do 
    xmllint --html --xmlout "$filename" | xmlstarlet sel -t -m '//body' -c './*' 
done < <(find "$1" -name '*.html' -print0) 

Примечание:

  • Используя find -print0 излучает NUL-разделители потока; IFS= read -r -d '' анализирует отдельные элементы этого потока таким образом, который устойчив ко всем возможным символам, которые могут существовать в именах файлов (включая пробелы, символы новой строки и т. Д.). См. UsingFind.
  • Замена <() является расширением ksh, принятым bash, zsh и другими. Убедитесь, что ваша оболочка #!/bin/bash (или аналогичная), а не #!/bin/sh; его преимущество по сравнению с традиционным конвейером заключается в том, что сеанс оболочки, выполняющийся xmllint, является тем же самым, который по-прежнему активен после цикла, что позволяет вам устанавливать переменные и делать другие изменения состояния, не отбрасывая их при выходе из конвейера (см. BashFAQ #24).
  • Использование xmllint --html --xmlout конвертирует из HTML в XML, чтобы гарантировать, что инструменты, поддерживающие XML, могут правильно разобрать ваш контент.
  • xmlstarlet sel принимает выражение XPath; //body - выражение XPath, которое находит тег тела в пространстве имен по умолчанию в любом месте вашего документа. (Теги поддерживающего тела в пространстве имен XHTML - это упражнение для читателя). См. the XMLStarlet documentation и the specification for XPath 1.0.
  • -c ./* говорит XMLStarlet излучать копию (отсюда -c) всего в соответствии с выражением XPath ./*, которая относится к содержанию под деталь непосредственно согласованный (таким образом, все, что внутри тела, но не тело сам элемент).
Смежные вопросы