2

So I have this pattern, the whole thing is one line

<img  itemprop="image"  class="hovered__image jsOpenGallery lazyload" data-src="//static.yellowpages.ca/ypca/ypui-6.65.0.0-20220419.0826/resources/images/serp/photo-gallery-icon.svg" alt="Drain King Plumbers - Plumbers & Plumbing Contractors"/><img  itemprop="image"  class="jsMerchantLogo lazyload" data-src="https://ssmscdn.yp.ca/image/resize/8bfbcba8-0a3e-48d3-b64b-16df5995779c/yp-serp-thumbnail/1.jpg" alt="Drain King Plumbers - Plumbers & Plumbing Contractors"/>

here I am using the expression "alt=" to find the tag and I need to get the name of the business after it like this from above code

alt="Drain King Plumbers - Plumbers & Plumbing Contractors"

The name can be anything, but it is always enclosed in " ". can I use grep to return something like alt="business name"

2

2 Answers 2

2

htmlq

You can use htmlq (Like jq, but for HTML.). Install it with brew: brew install htmlq and pipe your string to

| htmlq --attribute alt img

Check also for HTML pup, and xq for XML.

grep (PCREs)

A less elegant way (you can't really parse [X]HTML with regex) is to just use grep with --perl-regexp and --only-matching, with a regex using lookbehind:

| grep -Po "(?<= alt=\")[^\"]*"

Check also ripgrep.

2

If you want to tackle it in a more structured manner, you could

  • use xmllint to convert the input to valid XML (essentially adding a root element and replacing & characters by their entities)

  • use xmlstarlet to select the alt tag

  • (optionally) unescape the &amp; entity

ex. given

$ cat file
<img  itemprop="image"  class="hovered__image jsOpenGallery lazyload" data-src="//static.yellowpages.ca/ypca/ypui-6.65.0.0-20220419.0826/resources/images/serp/photo-gallery-icon.svg" alt="Drain King Plumbers - Plumbers & Plumbing Contractors"/><img  itemprop="image"  class="jsMerchantLogo lazyload" data-src="https://ssmscdn.yp.ca/image/resize/8bfbcba8-0a3e-48d3-b64b-16df5995779c/yp-serp-thumbnail/1.jpg" alt="Drain King Plumbers - Plumbers & Plumbing Contractors"/>

then

$ xmllint --html --xmlout --dropdtd file 2>/dev/null |
    xmlstarlet sel -t -v '//img/@alt' -n | xmlstarlet unesc
Drain King Plumbers - Plumbers & Plumbing Contractors
Drain King Plumbers - Plumbers & Plumbing Contractors

If you have kislyuk's yq: Command-line YAML/XML/TOML processor - jq wrapper for YAML, XML, TOML documents you can use xq instead of xmlstarlet - however the input still needs to be massaged into valid XML:

$ xmllint --html --xmlout --dropdtd file 2>/dev/null | xq '.. | .img? | .[]? | ."@alt"'
"Drain King Plumbers - Plumbers & Plumbing Contractors"
"Drain King Plumbers - Plumbers & Plumbing Contractors"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .