ChatGPT に jq スクリプトを直してもらった - 標準愚痴出力

標準愚痴出力

個人的なIT作業ログです。もしかしたら一般的に参考になることが書いているかもしれません(弱気

ChatGPT に jq スクリプトを直してもらった

先日書いたスクリプトは概ね問題なく動作していたのだが、json の末尾をうまく処理できていないのか、妙なエラーを出して終了する問題があった。

そこでダメで元々で ChatGPT に見てもらった。

次のようなjq スクリプトを書きました。概ね、うまく動作するのですが、最後の最後で jq: error (at <stdin>:0): Cannot index string with string "content" というエラーが表示されます。回避する方法はないでしょうか。スクリプト

.orderedItems[] |
.object |
select(.content | contains("エルデンリング")) |
    "```\n"+(.content |
        gsub("</p><p>";"\n\n") |
        gsub("<br[^>]*>";"  \n") |
        gsub("<a[^>]*href=\"(?<a>[^\"]*)\"[^>]*>(?<t>.*?)</a>";"["+.t+"]("+.a+")") |
        gsub("<[^>]*>";"")
    ) + "\n```\n**(" + (.published | tostring) + ")**\n"

回答

エラーメッセージ「jq: error (at \<stdin>:0): Cannot index string with string "content"」は、.contentフィールドが期待するオブジェクトではなく、文字列として扱われているために発生している可能性があります。つまり、select(.content)の部分で、.contentが存在しないか、オブジェクトではない場合にこのエラーが発生します。

以下のような方法で、contentフィールドが存在するかどうかをチェックし、存在する場合のみ処理を続けることでエラーを回避できます。

.orderedItems[] |
select(type == "object" and .content? and (.content | contains("エルデンリング"))) |
    "```\n"+(.content |
        gsub("</p><p>";"\n\n") |
        gsub("<br[^>]*>";"  \n") |
        gsub("<a[^>]*href=\"(?<a>[^\"]*)\"[^>]*>(?<t>.*?)</a>";"["+.t+"]("+.a+")") |
        gsub("<[^>]*>";"")
    ) + "\n```\n**(" + (.published | tostring) + ")**\n"

検証

結論からいうと、このスクリプト、そのままでは動かず、次のとおりに手直しが必要になった。

# tar -O -jxvf archive-*.tar.gz outbox.json | jq -rf mstdn-arc2txt.jq

.orderedItems[] |
.object |
select( type == "object" and .content? ) |
select(.content | contains("エルデンリング")) |
    "```\n"+(.content |
        gsub("</p><p>";"\n\n") |
        gsub("<br[^>]*>";"  \n") |
        gsub("<a[^>]*href=\"(?<a>[^\"]*)\"[^>]*>(?<t>.*?)</a>";"["+.t+"]("+.a+")") |
        gsub("<[^>]*>";"")
    ) + "\n```\n**(" + (.published | tostring) + ")**\n"

何がいけなかったかというと、見る階層を一つ深くしている .object | が抜けていたためだった。そこを直すとうまくいった。

あと、質問のテキストを見直してみると、ペーストした時にコード中の文字列定数に含まれる ``` がコード開始/終了のマークと誤認されてしまっていた。そういうので AI のコード認識を誤らせてしまっていたのかもしれない。

いずれにせよ、やはりAI の類を利用する時はアウトプットについての検証が必要不可欠だねぇ。