大佬萌们,如何从JQ中取出数组赋值给变量

@Ta 10-25 03:44 3462点击
没用户JQ,只能如图这样取出来吗,这样我后续虽然能够遍历出来,但是是不是前面有更好的办法直接取出赋给变量。



Screenshot_2022-10-25-00-46-14-750_com.termux.jpg(662.45 KB)
回复列表(14)
  • @Ta / 10-25 12:12 / /

    @庸人,你传一下原始 json 文件,和写一下你期望得到的结果呗?

  • @Ta / 10-25 20:14 / /
    @无名啊,格式就是这样(图下),我主要取出元素playlist下面的所有name元素数组(.playlist[].name),然后有没有办法直接将其结果赋给脚本内变量数组(不想每次都调用),我下图用的循环取出方法,有没有更简单的
    Screenshot_2022-10-25-20-08-20-146_bin.mt.plus.jpg(562.67 KB)Screenshot_2022-10-25-19-59-39-914_bin.mt.plus.jpg(535.46 KB)
  • @Ta / 10-25 21:33 / /

    @庸人,直接回答:可以用 Bashreadarray 来一次性读到某个数组

    另外:

    1. Bash Shell 更适合交互式和简单脚本使用。含有数组、字典甚至更复杂数据结构的,可能都值得你考虑换其他语言了
    2. 不想换的话,考虑尽量用 jq 来一次性生成你最终要的数据?
  • @Ta / 10-25 22:01 / /

    @庸人,比如:

    $ readarray -td $'\0' arr < <(jq -rj '[.[].name] | join("\u0000")' <<<'[{"id": 1, "name": "a\nb\n"}, {"id": 2, "name": "c\nd"}]')
    $ declare -p arr
    declare -a arr=([0]=$'a\nb\n' [1]=$'c\nd')
    

    如果你不担心你的 name 里有换行符的话,可以直接:

    $ readarray -t arr < <(jq -r '.[].name' <<<'[{"id": 1, "name": "ab"}, {"id": 2, "name": "cd"}]')
    $ declare -p arr
    declare -a arr=([0]='ab' [1]='cd')
    
  • @Ta / 10-25 22:19 / /
    @无名啊,感谢大佬么么,其实我用的就是bash,,只是很不熟,太菜了之前看到过这个不过我在termux终端测试输入没有高亮我以为不支持🤣🤣
  • @Ta / 10-25 22:23 / /

    @庸人,你说下原始需求,感觉会有更好的实现方式

  • @Ta / 10-25 22:47 / /
    @无名啊,其实就是将name→歌曲名和id又歌曲id放进两个数组变量里🤣。
    因为我看jq就是按行输出的,所以想到有没有办法直接放进数组里而不用再去循环遍历一次。后面要用了就直接调用数组了
  • @Ta / 10-25 22:53 / /

    @庸人,你的需求是要备份当下的网易云歌单吗?还是啥。。

  • @Ta / 10-25 23:08 / /
    @无名啊,没呢我闲着写的,用的git上的网易云音乐api,想写个实现本地化命令行的一些操作,读取本地json是不想一直都向api请求。哈哈🤣🤣
  • @Ta / 10-26 09:23 / /
    @无名啊,大佬能不能细说一下你上面的命令,命令不怎么熟有点看不懂,主要是我其实更习惯用管道这样的方式<<这样定向的方式我看不太懂IMG_20221026_090956.jpg(52.86 KB)

    如上图,我输出所有数组能得到下图这样,当然加了个nl命令
    (38.08 KB)

    但是当我单拧出来一个数组,那么结尾就会有一个换行🤣🤣

    IMG_20221026_092008.jpg(73.62 KB)
    IMG_20221026_092036.jpg(40.66 KB)
  • @Ta / 10-26 09:25 / /
    图2挂了,这里
    IMG_20221026_091024.jpg(38.08 KB)
  • @Ta / 10-26 11:09 / /

    @庸人

    主要是我其实更习惯用管道这样的方式

    不能在匿名管道内修改外部的变量!(如:jq | readarraysum=0; seq 3 | while read -r i; do (( sum += i )); done

    理由

    因为这会开启一个子 shell,然后在子 shell 中,readarrayjq 的输出转成数组。

    等这一行执行完毕,子 shell 就会退出,刚整理好的数组也随着进程结束而消失了。

    那用啥?

    所以,只能用 <<<< <(...) 的形式。

    • 前者需要完全准备好一个字符串,再作为 stdin 喂给所在的命令。我觉得没必要,没这么干

      (试想,你拷贝一个 1GB 的文件,会申请 1GB 的内存,全部读取完成后,再写入至新文件吗?)

    • 后者,<(...) 是将 ...stdout 重定向至某个文件(一般是具名管道),然后将此文件作为 stdin 喂给所在命令

      (如果是管道实现,则一般是 4KB 缓冲区)

    但是当我单拧出来一个数组,那么结尾就会有一个换行🤣🤣

    使用 readarray 时指定 -t 参数,会自动删除行末的换行符

  • @Ta / 10-26 11:17 / /
    @无名啊,这我了解过一些,之前用while read line发现了<<<这个我多少还知道些,就是后面<<和<含义我不太清楚,一会儿我实践操练去
  • @Ta / 10-26 13:08 / /
    @无名啊,好吧,我太笨了,我陷入了一个误区,就是因为-t删除了换行符,我的想法是想换行展示出来的,直接printf "%s\n"其实就行了🤣🤣
添加新回复
回复需要登录