Diary

Diary

日々学んだことをアウトプットする場として初めてみました

ワンライナーでid のかぶりがないかチェック

ワンライナーでid のかぶりがないかチェック

id というのはユニークである必要がありますが、自分で命名してると下手し被ってしまうことがあると思います。

そこで今回は、HTML をユースケースとして、id に被りがないかをチェックするワンライナーを書いてみました

HTML を確認する

今回考えたい HTML として、以下のように被りのある test.html を用意しました。

$ cat text.html
<html>
  <div class="container">
    <div id="hoge">
      <div id="pien">
        <img src="" alt="" id="img">
      </div>
    </div>
    <p id="hoge"></p>
  </div>
</html>

id を取ってくる

一致する部分をとってくるには、grep を用います

$ cat test.html | grep id
    <div id="hoge">
      <div id="pien">
        <img src="" alt="" id="img">
    <p id="hoge"></p>

ただこのままだと、p タグと div タグの違いを区別できないので、id="<something>"に絞って、一致部分を広げてみます。

今回の例では、必ず

  • id名はダブルクォーテーションで括る
  • id=と""の間はスペースを入れない

と書かれることを想定しています。

$ cat test.html | grep 'id="[^"]*"'

一致部分のみ取り出す

ただ今のままでは1行丸々取り出してきてしまって比較しにくいので、一致部分のみを取り出してくるように変更します。

そのためには、-o オプションを使います。

$ cat test.html | grep -o 'id="[^"]*"'
id="hoge"
id="pien"
id="img"
id="hoge"

余談ですが、grep -oを用いて1文字ずつ出力するシェル芸として次のようなものがあります

# . で全ての文字列にヒットされる
$ cat test.html | grep -o .
<
h
t
m
l
>

被りがどうなるかチェックする

被りチェックなのでuniqを使いたいところですが、uniqを使うときには必ずsortを挟みます(暗記)

# sort を挟まない場合
$ cat test.html | grep -o 'id="[^"]*"' | uniq
id="hoge"
id="pien"
id="img"
id="hoge"

# sort を挟むと
$ cat test.html | grep -o 'id="[^"]*"' | sort | uniq
id="hoge"
id="img"
id="pien"

さらに、「被りのある行」のみを取り出したいために -d オプションをもちいます。

$ cat test.html | grep -o 'id="[^"]*"' | sort | uniq -d
id="hoge"

おわりに