{"id":13760844,"url":"https://github.com/aduros/pjs","last_synced_at":"2026-03-14T00:17:36.820Z","repository":{"id":41436137,"uuid":"331172276","full_name":"aduros/pjs","owner":"aduros","description":"An awk-like command-line tool for processing text, CSV, JSON, HTML, and XML.","archived":false,"fork":false,"pushed_at":"2021-01-30T02:14:03.000Z","size":312,"stargazers_count":24,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-22T04:17:19.453Z","etag":null,"topics":["awk","cli","cut","grep","jq","pipe","sed","shell","sort","uniq","wc"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aduros.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-01-20T02:42:19.000Z","updated_at":"2024-08-22T07:29:31.000Z","dependencies_parsed_at":"2022-09-18T21:38:48.233Z","dependency_job_id":null,"html_url":"https://github.com/aduros/pjs","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/aduros/pjs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aduros%2Fpjs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aduros%2Fpjs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aduros%2Fpjs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aduros%2Fpjs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aduros","download_url":"https://codeload.github.com/aduros/pjs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aduros%2Fpjs/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259642287,"owners_count":22888987,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["awk","cli","cut","grep","jq","pipe","sed","shell","sort","uniq","wc"],"created_at":"2024-08-03T13:01:24.006Z","updated_at":"2026-03-14T00:17:36.787Z","avatar_url":"https://github.com/aduros.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# pjs\n\n**pjs** is a command-line tool for filtering and transforming text, similar to `awk`. You provide it\npowerful one-line snippets written in vanilla JavaScript. It supports many input formats, including\nplain text, CSV, JSON, HTML, and XML.\n\npjs works by generating a complete JS program from the provided script, and feeding it each line of\nstandard input. The statically generated program can be reviewed with `--explain`.\n\nSee the [examples](#examples) section below to see what pjs can do. For complete documentation, read\nthe [manual](doc/manual.md) or run `man pjs`.\n\n# Installing\n\nInstall the `pjs` command with `npm`:\n\n```sh\nnpm install -g pjs-tool\n```\n\nIf `npm` is not available on your environment, you can download a [standalone\nexecutable](https://aduros.com/pjs/pjs-latest.tar.bz2). You will still need `node` installed.\n\n# Examples\n\nClick on an example to run it in your browser at the [pjs playground](https://aduros.com/pjs).\n\n## Transforming Examples\n\nConvert a file to upper-case:\n\n[`cat input.txt | pjs '_.toUpperCase()'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20'_.toUpperCase()'%22%2C%22input%22%3A%22There%20once%20was%20a%20man%20from%20Nantucket%5CnWho%20kept%20all%20his%20cash%20in%20a%20bucket.%5CnBut%20his%20daughter%20named%20Nan%2C%5CnRan%20away%20with%20a%20man%5CnAnd%20as%20for%20the%20bucket%2C%20Nantucket.%22%7D)\n\nPrint the second field of each line (in this example, the PIDs):\n\n[`ps aux | pjs '$1'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20'%241'%22%2C%22input%22%3A%22USER%20%20%20%20%20%20%20%20%20PID%20%25CPU%20%25MEM%20%20%20%20VSZ%20%20%20RSS%20TTY%20%20%20%20%20%20STAT%20START%20%20%20TIME%20COMMAND%5Cnsyslog%20%20%20%20%20%20%20643%20%200.0%20%200.0%20221124%20%204760%20%3F%20%20%20%20%20%20%20%20Ssl%20%20Jan28%20%20%200%3A00%20%2Fusr%2Fsbin%2Frsyslogd%20-n%20-iNONE%5Cnroot%20%20%20%20%20%20%20%20%20653%20%200.0%20%200.1%20%2018172%20%208712%20%3F%20%20%20%20%20%20%20%20Ss%20%20%20Jan28%20%20%200%3A04%20%2Flib%2Fsystemd%2Fsystemd-logind%5Cnroot%20%20%20%20%20%20%20%20%20654%20%200.2%20%200.1%20274952%20%209944%20%3F%20%20%20%20%20%20%20%20Ssl%20%20Jan28%20%20%202%3A40%20%2Fusr%2Fsbin%2Fthermald%20--systemd%20--d%5Cnroot%20%20%20%20%20%20%20%20%20655%20%200.0%20%200.1%20393916%2012676%20%3F%20%20%20%20%20%20%20%20Ssl%20%20Jan28%20%20%200%3A07%20%2Fusr%2Flibexec%2Fudisks2%2Fudisksd%5Cnroot%20%20%20%20%20%20%20%20%20657%20%200.0%20%200.1%20%2015208%20%208124%20%3F%20%20%20%20%20%20%20%20Ss%20%20%20Jan28%20%20%200%3A00%20%2Fsbin%2Fwpa_supplicant%20-u%20-s%20-O%20%2Fr%5Cnavahi%20%20%20%20%20%20%20%20666%20%200.0%20%200.0%20%20%209224%20%20%20324%20%3F%20%20%20%20%20%20%20%20S%20%20%20%20Jan28%20%20%200%3A00%20avahi-daemon%3A%20chroot%20helper%5Cnroot%20%20%20%20%20%20%20%20%20710%20%200.0%20%200.1%20306056%20%208344%20%3F%20%20%20%20%20%20%20%20SLsl%20Jan28%20%20%200%3A02%20%2Fusr%2Fsbin%2Flightdm%5Cnroot%20%20%20%20%20%20%20%20%20715%20%200.0%20%200.1%20315100%20%209992%20%3F%20%20%20%20%20%20%20%20Ssl%20%20Jan28%20%20%200%3A00%20%2Fusr%2Fsbin%2FModemManager%22%7D)\n\nPrint all fields after the 10th (in this example, the process names):\n\n[`ps aux | pjs '$.slice(10).join(\" \")'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20'%24.slice(10).join(%5C%22%20%5C%22)'%22%2C%22input%22%3A%22USER%20%20%20%20%20%20%20%20%20PID%20%25CPU%20%25MEM%20%20%20%20VSZ%20%20%20RSS%20TTY%20%20%20%20%20%20STAT%20START%20%20%20TIME%20COMMAND%5Cnsyslog%20%20%20%20%20%20%20643%20%200.0%20%200.0%20221124%20%204760%20%3F%20%20%20%20%20%20%20%20Ssl%20%20Jan28%20%20%200%3A00%20%2Fusr%2Fsbin%2Frsyslogd%20-n%20-iNONE%5Cnroot%20%20%20%20%20%20%20%20%20653%20%200.0%20%200.1%20%2018172%20%208712%20%3F%20%20%20%20%20%20%20%20Ss%20%20%20Jan28%20%20%200%3A04%20%2Flib%2Fsystemd%2Fsystemd-logind%5Cnroot%20%20%20%20%20%20%20%20%20654%20%200.2%20%200.1%20274952%20%209944%20%3F%20%20%20%20%20%20%20%20Ssl%20%20Jan28%20%20%202%3A40%20%2Fusr%2Fsbin%2Fthermald%20--systemd%20--d%5Cnroot%20%20%20%20%20%20%20%20%20655%20%200.0%20%200.1%20393916%2012676%20%3F%20%20%20%20%20%20%20%20Ssl%20%20Jan28%20%20%200%3A07%20%2Fusr%2Flibexec%2Fudisks2%2Fudisksd%5Cnroot%20%20%20%20%20%20%20%20%20657%20%200.0%20%200.1%20%2015208%20%208124%20%3F%20%20%20%20%20%20%20%20Ss%20%20%20Jan28%20%20%200%3A00%20%2Fsbin%2Fwpa_supplicant%20-u%20-s%20-O%20%2Fr%5Cnavahi%20%20%20%20%20%20%20%20666%20%200.0%20%200.0%20%20%209224%20%20%20324%20%3F%20%20%20%20%20%20%20%20S%20%20%20%20Jan28%20%20%200%3A00%20avahi-daemon%3A%20chroot%20helper%5Cnroot%20%20%20%20%20%20%20%20%20710%20%200.0%20%200.1%20306056%20%208344%20%3F%20%20%20%20%20%20%20%20SLsl%20Jan28%20%20%200%3A02%20%2Fusr%2Fsbin%2Flightdm%5Cnroot%20%20%20%20%20%20%20%20%20715%20%200.0%20%200.1%20315100%20%209992%20%3F%20%20%20%20%20%20%20%20Ssl%20%20Jan28%20%20%200%3A00%20%2Fusr%2Fsbin%2FModemManager%22%7D)\n\nRemove trailing whitespace from each line in a file:\n\n`cat document.txt | pjs '_.replace(/\\s*$/, \"\")'`\n\n## Filtering Examples\n\nGiven a list of numbers, print only numbers greater than 5:\n\n[`seq 1 10 | pjs '_ \u003e 5'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20'_%20%3E%205'%22%2C%22input%22%3A%221%5Cn2%5Cn3%5Cn4%5Cn5%5Cn6%5Cn7%5Cn8%5Cn9%5Cn10%22%7D)\n\nGiven a list of numbers, print only even numbers:\n\n[`seq 1 10 | pjs '_ % 2 == 0'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20'_%20%25%202%20%3D%3D%200'%22%2C%22input%22%3A%221%5Cn2%5Cn3%5Cn4%5Cn5%5Cn6%5Cn7%5Cn8%5Cn9%5Cn10%22%7D)\n\nPrint the last 4 lines of a file (like `tail`):\n\n[`seq 1 10 | pjs --after 'LINES.slice(-4).join(\"\\n\")'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20--after%20'LINES.slice(-4).join(%5C%22%5C%5Cn%5C%22)'%22%2C%22input%22%3A%221%5Cn2%5Cn3%5Cn4%5Cn5%5Cn6%5Cn7%5Cn8%5Cn9%5Cn10%22%7D)\n\nPrint every other line of a file:\n\n[`cat input.txt | pjs 'COUNT % 2 == 1'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20'COUNT%20%25%202%20%3D%3D%201'%22%2C%22input%22%3A%22There%20once%20was%20a%20man%20from%20Nantucket%5CnWho%20kept%20all%20his%20cash%20in%20a%20bucket.%5CnBut%20his%20daughter%20named%20Nan%2C%5CnRan%20away%20with%20a%20man%5CnAnd%20as%20for%20the%20bucket%2C%20Nantucket.%22%7D)\n\nGiven a list of filenames, print the files that actually exist:\n\n`cat filenames.txt | pjs 'fs.existsSync(_)'`\n\nGiven a list of filenames, print the files that are under one kilobyte in size:\n\n`cat filenames.txt | pjs 'fs.statSync(_).size \u003c 1000'`\n\n## Summarizing Examples\n\nManually count the lines in the input (like `wc -l`):\n\n[`cat input.txt | pjs '{ count++ }' --after 'count'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20'%7B%20count%2B%2B%20%7D'%20--after%20'count'%22%2C%22input%22%3A%22There%20once%20was%20a%20man%20from%20Nantucket%5CnWho%20kept%20all%20his%20cash%20in%20a%20bucket.%5CnBut%20his%20daughter%20named%20Nan%2C%5CnRan%20away%20with%20a%20man%5CnAnd%20as%20for%20the%20bucket%2C%20Nantucket.%22%7D)\n\nSame as above, but using the built-in `COUNT` variable:\n\n[`cat input.txt | pjs --after 'COUNT'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20--after%20'COUNT'%22%2C%22input%22%3A%22There%20once%20was%20a%20man%20from%20Nantucket%5CnWho%20kept%20all%20his%20cash%20in%20a%20bucket.%5CnBut%20his%20daughter%20named%20Nan%2C%5CnRan%20away%20with%20a%20man%5CnAnd%20as%20for%20the%20bucket%2C%20Nantucket.%22%7D)\n\nCount the *unique* lines in the input:\n\n[`cat input.txt | pjs --before 'let s = new Set()' '{ s.add(_) }' --after 's.size'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20--before%20'let%20s%20%3D%20new%20Set()'%20'%7B%20s.add(_)%20%7D'%20--after%20's.size'%22%2C%22input%22%3A%22Laid%20back%2C%5CnLaid%20back%2C%5CnLaid%20back%20we'll%20give%20you%20play%20back.%5CnLaid%20back%2C%5CnLaid%20back%2C%5CnLaid%20back%20I'll%20give%20you%20play%20back.%22%7D)\n\nManually sort the lines of the input (like `sort`)\n\n[`cat input.txt | pjs --before 'let lines = []' '{ lines.push(_) }' --after 'lines.sort().join(\"\\n\")'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20--before%20'let%20lines%20%3D%20%5B%5D'%20'%7B%20lines.push(_)%20%7D'%20--after%20'lines.sort().join(%5C%22%5C%5Cn%5C%22)'%22%2C%22input%22%3A%22There%20once%20was%20a%20man%20from%20Nantucket%5CnWho%20kept%20all%20his%20cash%20in%20a%20bucket.%5CnBut%20his%20daughter%20named%20Nan%2C%5CnRan%20away%20with%20a%20man%5CnAnd%20as%20for%20the%20bucket%2C%20Nantucket.%22%7D)\n\nSame as above, but using the built-in `LINES` variable:\n\n[`cat input.txt | pjs --after 'LINES.sort().join(\"\\n\")'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20--after%20'LINES.sort().join(%5C%22%5C%5Cn%5C%22)'%22%2C%22input%22%3A%22There%20once%20was%20a%20man%20from%20Nantucket%5CnWho%20kept%20all%20his%20cash%20in%20a%20bucket.%5CnBut%20his%20daughter%20named%20Nan%2C%5CnRan%20away%20with%20a%20man%5CnAnd%20as%20for%20the%20bucket%2C%20Nantucket.%22%7D)\n\n## CSV Examples\n\nGiven a `grades.csv` file that looks like this:\n\n```csv\nname,subject,grade\nBob,physics,43\nAlice,biology,75\nAlice,physics,90\nDavid,biology,85\nClara,physics,78\n```\n\nPrint only the third column:\n\n[`cat grades.csv | pjs --csv '$2'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20--csv%20'%242'%22%2C%22input%22%3A%22name%2Csubject%2Cgrade%5CnBob%2Cphysics%2C43%5CnAlice%2Cbiology%2C75%5CnAlice%2Cphysics%2C90%5CnDavid%2Cbiology%2C85%5CnClara%2Cphysics%2C78%22%7D)\n\nPrint the grades using the column header:\n\n[`cat grades.csv | pjs --csv-header '_.grade'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20--csv-header%20'_.grade'%22%2C%22input%22%3A%22name%2Csubject%2Cgrade%5CnBob%2Cphysics%2C43%5CnAlice%2Cbiology%2C75%5CnAlice%2Cphysics%2C90%5CnDavid%2Cbiology%2C85%5CnClara%2Cphysics%2C78%22%7D)\n\nPrint the names of students taking biology:\n\n[`cat grades.csv | pjs --csv-header '_.subject == \"biology\" \u0026\u0026 _.name'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20--csv-header%20'_.subject%20%3D%3D%20%5C%22biology%5C%22%20%26%26%20_.name'%22%2C%22input%22%3A%22name%2Csubject%2Cgrade%5CnBob%2Cphysics%2C43%5CnAlice%2Cbiology%2C75%5CnAlice%2Cphysics%2C90%5CnDavid%2Cbiology%2C85%5CnClara%2Cphysics%2C78%22%7D)\n\nPrint the average grade across all courses:\n\n[`cat grades.csv | pjs --csv-header '{ sum += Number(_.grade) }' --after 'sum/COUNT'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20--csv-header%20'%7B%20sum%20%2B%3D%20Number(_.grade)%20%7D'%20--after%20'sum%2FCOUNT'%22%2C%22input%22%3A%22name%2Csubject%2Cgrade%5CnBob%2Cphysics%2C43%5CnAlice%2Cbiology%2C75%5CnAlice%2Cphysics%2C90%5CnDavid%2Cbiology%2C85%5CnClara%2Cphysics%2C78%22%7D)\n\n## JSON Examples\n\nGiven a `users.json` file that looks like this:\n\n```json\n{\n  \"version\": 123,\n  \"items\": [\n    {\"name\": {\"first\": \"Winifred\", \"last\": \"Frost\"}, \"age\": 42},\n    {\"name\": {\"first\": \"Miles\", \"last\": \"Fernandez\"}, \"age\": 15},\n    {\"name\": {\"first\": \"Kennard\", \"last\": \"Floyd\"}, \"age\": 20},\n    {\"name\": {\"first\": \"Lonnie\", \"last\": \"Davis\"}, \"age\": 78},\n    {\"name\": {\"first\": \"Duncan\", \"last\": \"Poole\"}, \"age\": 36}\n  ]\n}\n```\n\nPrint the value of the \"version\" field:\n\n[`cat users.json | pjs --json '.version' _`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20--json%20'.version'%20_%22%2C%22input%22%3A%22%7B%5Cn%20%20%5C%22version%5C%22%3A%20123%2C%5Cn%20%20%5C%22items%5C%22%3A%20%5B%5Cn%20%20%20%20%7B%5C%22name%5C%22%3A%20%7B%5C%22first%5C%22%3A%20%5C%22Winifred%5C%22%2C%20%5C%22last%5C%22%3A%20%5C%22Frost%5C%22%7D%2C%20%5C%22age%5C%22%3A%2042%7D%2C%5Cn%20%20%20%20%7B%5C%22name%5C%22%3A%20%7B%5C%22first%5C%22%3A%20%5C%22Miles%5C%22%2C%20%5C%22last%5C%22%3A%20%5C%22Fernandez%5C%22%7D%2C%20%5C%22age%5C%22%3A%2015%7D%2C%5Cn%20%20%20%20%7B%5C%22name%5C%22%3A%20%7B%5C%22first%5C%22%3A%20%5C%22Kennard%5C%22%2C%20%5C%22last%5C%22%3A%20%5C%22Floyd%5C%22%7D%2C%20%5C%22age%5C%22%3A%2020%7D%2C%5Cn%20%20%20%20%7B%5C%22name%5C%22%3A%20%7B%5C%22first%5C%22%3A%20%5C%22Lonnie%5C%22%2C%20%5C%22last%5C%22%3A%20%5C%22Davis%5C%22%7D%2C%20%5C%22age%5C%22%3A%2078%7D%2C%5Cn%20%20%20%20%7B%5C%22name%5C%22%3A%20%7B%5C%22first%5C%22%3A%20%5C%22Duncan%5C%22%2C%20%5C%22last%5C%22%3A%20%5C%22Poole%5C%22%7D%2C%20%5C%22age%5C%22%3A%2036%7D%5Cn%20%20%5D%5Cn%7D%22%7D)\n\nPrint the full name of each user:\n\n[`cat users.json | pjs --json '.items[].name' '_.first+\" \"+_.last'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20--json%20'.items%5B%5D.name'%20'_.first%2B%5C%22%20%5C%22%2B_.last'%22%2C%22input%22%3A%22%7B%5Cn%20%20%5C%22version%5C%22%3A%20123%2C%5Cn%20%20%5C%22items%5C%22%3A%20%5B%5Cn%20%20%20%20%7B%5C%22name%5C%22%3A%20%7B%5C%22first%5C%22%3A%20%5C%22Winifred%5C%22%2C%20%5C%22last%5C%22%3A%20%5C%22Frost%5C%22%7D%2C%20%5C%22age%5C%22%3A%2042%7D%2C%5Cn%20%20%20%20%7B%5C%22name%5C%22%3A%20%7B%5C%22first%5C%22%3A%20%5C%22Miles%5C%22%2C%20%5C%22last%5C%22%3A%20%5C%22Fernandez%5C%22%7D%2C%20%5C%22age%5C%22%3A%2015%7D%2C%5Cn%20%20%20%20%7B%5C%22name%5C%22%3A%20%7B%5C%22first%5C%22%3A%20%5C%22Kennard%5C%22%2C%20%5C%22last%5C%22%3A%20%5C%22Floyd%5C%22%7D%2C%20%5C%22age%5C%22%3A%2020%7D%2C%5Cn%20%20%20%20%7B%5C%22name%5C%22%3A%20%7B%5C%22first%5C%22%3A%20%5C%22Lonnie%5C%22%2C%20%5C%22last%5C%22%3A%20%5C%22Davis%5C%22%7D%2C%20%5C%22age%5C%22%3A%2078%7D%2C%5Cn%20%20%20%20%7B%5C%22name%5C%22%3A%20%7B%5C%22first%5C%22%3A%20%5C%22Duncan%5C%22%2C%20%5C%22last%5C%22%3A%20%5C%22Poole%5C%22%7D%2C%20%5C%22age%5C%22%3A%2036%7D%5Cn%20%20%5D%5Cn%7D%22%7D)\n\nPrint the users that are older than 21:\n\n[`cat users.json | pjs --json '.items[]' '_.age \u003e= 21'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20--json%20'.items%5B%5D'%20'_.age%20%3E%3D%2021'%22%2C%22input%22%3A%22%7B%5Cn%20%20%5C%22version%5C%22%3A%20123%2C%5Cn%20%20%5C%22items%5C%22%3A%20%5B%5Cn%20%20%20%20%7B%5C%22name%5C%22%3A%20%7B%5C%22first%5C%22%3A%20%5C%22Winifred%5C%22%2C%20%5C%22last%5C%22%3A%20%5C%22Frost%5C%22%7D%2C%20%5C%22age%5C%22%3A%2042%7D%2C%5Cn%20%20%20%20%7B%5C%22name%5C%22%3A%20%7B%5C%22first%5C%22%3A%20%5C%22Miles%5C%22%2C%20%5C%22last%5C%22%3A%20%5C%22Fernandez%5C%22%7D%2C%20%5C%22age%5C%22%3A%2015%7D%2C%5Cn%20%20%20%20%7B%5C%22name%5C%22%3A%20%7B%5C%22first%5C%22%3A%20%5C%22Kennard%5C%22%2C%20%5C%22last%5C%22%3A%20%5C%22Floyd%5C%22%7D%2C%20%5C%22age%5C%22%3A%2020%7D%2C%5Cn%20%20%20%20%7B%5C%22name%5C%22%3A%20%7B%5C%22first%5C%22%3A%20%5C%22Lonnie%5C%22%2C%20%5C%22last%5C%22%3A%20%5C%22Davis%5C%22%7D%2C%20%5C%22age%5C%22%3A%2078%7D%2C%5Cn%20%20%20%20%7B%5C%22name%5C%22%3A%20%7B%5C%22first%5C%22%3A%20%5C%22Duncan%5C%22%2C%20%5C%22last%5C%22%3A%20%5C%22Poole%5C%22%7D%2C%20%5C%22age%5C%22%3A%2036%7D%5Cn%20%20%5D%5Cn%7D%22%7D)\n\nPrint the ages of the first 3 users only:\n\n[`cat users.json | pjs --json '.items[0:3]' '_.age'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20--json%20'.items%5B0%3A3%5D'%20'_.age'%22%2C%22input%22%3A%22%7B%5Cn%20%20%5C%22version%5C%22%3A%20123%2C%5Cn%20%20%5C%22items%5C%22%3A%20%5B%5Cn%20%20%20%20%7B%5C%22name%5C%22%3A%20%7B%5C%22first%5C%22%3A%20%5C%22Winifred%5C%22%2C%20%5C%22last%5C%22%3A%20%5C%22Frost%5C%22%7D%2C%20%5C%22age%5C%22%3A%2042%7D%2C%5Cn%20%20%20%20%7B%5C%22name%5C%22%3A%20%7B%5C%22first%5C%22%3A%20%5C%22Miles%5C%22%2C%20%5C%22last%5C%22%3A%20%5C%22Fernandez%5C%22%7D%2C%20%5C%22age%5C%22%3A%2015%7D%2C%5Cn%20%20%20%20%7B%5C%22name%5C%22%3A%20%7B%5C%22first%5C%22%3A%20%5C%22Kennard%5C%22%2C%20%5C%22last%5C%22%3A%20%5C%22Floyd%5C%22%7D%2C%20%5C%22age%5C%22%3A%2020%7D%2C%5Cn%20%20%20%20%7B%5C%22name%5C%22%3A%20%7B%5C%22first%5C%22%3A%20%5C%22Lonnie%5C%22%2C%20%5C%22last%5C%22%3A%20%5C%22Davis%5C%22%7D%2C%20%5C%22age%5C%22%3A%2078%7D%2C%5Cn%20%20%20%20%7B%5C%22name%5C%22%3A%20%7B%5C%22first%5C%22%3A%20%5C%22Duncan%5C%22%2C%20%5C%22last%5C%22%3A%20%5C%22Poole%5C%22%7D%2C%20%5C%22age%5C%22%3A%2036%7D%5Cn%20%20%5D%5Cn%7D%22%7D)\n\nQuery a web API for users:\n\n```sh\ncurl -A \"\" 'https://www.instagram.com/web/search/topsearch/?query=John' |\n    pjs --json '.users[].user' '`@${_.username} (${_.full_name})`'\n```\n\n## HTML/XML Examples\n\nPrint the text of all `\u003ch1\u003e` and `\u003ch2\u003e` elements on a web page:\n\n[`cat page.html | pjs --html 'h1,h2' '_.text'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20--html%20'h1%2Ch2'%20'_.text'%22%2C%22input%22%3A%22%3Chtml%3E%5Cn%3Cbody%3E%5Cn%20%20%3Ch1%3EWelcome%20To%20My%20Geocities%20Homepage%3C%2Fh1%3E%5Cn%5Cn%20%20%3Cdiv%3E%5Cn%20%20%20%20Under%20CONSTRUCTION%5Cn%20%20%20%20%3Cimg%20src%3D%5C%22construction.gif%5C%22%3E%5Cn%20%20%3C%2Fdiv%3E%5Cn%5Cn%20%20%3Cimg%20src%3D%5C%22dancing-baby.gif%5C%22%3E%5Cn%5Cn%20%20%3Cdiv%3E%5Cn%20%20%20%20Visitor%20counter%3A%20%3Cspan%20id%3D%5C%22counter%5C%22%3E1234%3C%2Fspan%3E%5Cn%20%20%3C%2Fdiv%3E%5Cn%5Cn%20%20%3Ch1%3EGuestbook%3C%2Fh1%3E%5Cn%5Cn%20%20Sign%20my%20%3Ca%20href%3D%5C%22guestbook.html%5C%22%3EGuestbook!%3C%2Fa%3E%5Cn%3C%2Fbody%3E%5Cn%3C%2Fhtml%3E%22%7D)\n\nPrint the URLs of all images on a web page:\n\n[`cat page.html | pjs --html 'img' '_.attr.src'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20--html%20'img'%20'_.attr.src'%22%2C%22input%22%3A%22%3Chtml%3E%5Cn%3Cbody%3E%5Cn%20%20%3Ch1%3EWelcome%20To%20My%20Geocities%20Homepage%3C%2Fh1%3E%5Cn%5Cn%20%20%3Cdiv%3E%5Cn%20%20%20%20Under%20CONSTRUCTION%5Cn%20%20%20%20%3Cimg%20src%3D%5C%22construction.gif%5C%22%3E%5Cn%20%20%3C%2Fdiv%3E%5Cn%5Cn%20%20%3Cimg%20src%3D%5C%22dancing-baby.gif%5C%22%3E%5Cn%5Cn%20%20%3Cdiv%3E%5Cn%20%20%20%20Visitor%20counter%3A%20%3Cspan%20id%3D%5C%22counter%5C%22%3E1234%3C%2Fspan%3E%5Cn%20%20%3C%2Fdiv%3E%5Cn%5Cn%20%20%3Ch1%3EGuestbook%3C%2Fh1%3E%5Cn%5Cn%20%20Sign%20my%20%3Ca%20href%3D%5C%22guestbook.html%5C%22%3EGuestbook!%3C%2Fa%3E%5Cn%3C%2Fbody%3E%5Cn%3C%2Fhtml%3E%22%7D)\n\nScrape headlines off a news site using a complex CSS selector:\n\n```sh\ncurl https://news.ycombinator.com | pjs '_.text' \\\n    --html 'table table tr:nth-last-of-type(n+2) td:nth-child(3)'\n```\n\nPrint all links in `\u003ch2\u003e` elements with URLs containing the word \"blog\":\n\n```sh\ncurl https://aduros.com | pjs --html 'h2 a' '_.attr.href.includes(\"blog\") \u0026\u0026 _.attr.href'\n```\n\nPrint a readable summary of an RSS feed:\n\n```sh\ncurl https://aduros.com/index.xml | pjs --xml 'item' \\\n    '_.querySelector(\"title\").text + \" --\u003e \" + _.querySelector(\"link\").text'\n```\n\n## Advanced Examples\n\nBulk rename \\*.jpeg files to \\*.jpg:\n\n```sh\nfind -name '*.jpeg' | pjs 'let f = path.parse(_);\n    fs.renameSync(_, path.join(f.dir, f.name+\".jpg\"))'\n```\n\nPrint the longest line in the input:\n\n[`cat input.txt | pjs 'if (_.length \u003e m) { m = _.length; longest = _ }' --after 'longest'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20'if%20(_.length%20%3E%20m)%20%7B%20m%20%3D%20_.length%3B%20longest%20%3D%20_%20%7D'%20--after%20'longest'%22%2C%22input%22%3A%22There%20once%20was%20a%20man%20from%20Nantucket%5CnWho%20kept%20all%20his%20cash%20in%20a%20bucket.%5CnBut%20his%20daughter%20named%20Nan%2C%5CnRan%20away%20with%20a%20man%5CnAnd%20as%20for%20the%20bucket%2C%20Nantucket.%22%7D)\n\nCount the words in the input:\n\n[`cat input.txt | pjs '{ words += $.length }' --after 'words'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20'%7B%20words%20%2B%3D%20%24.length%20%7D'%20--after%20'words'%22%2C%22input%22%3A%22There%20once%20was%20a%20man%20from%20Nantucket%5CnWho%20kept%20all%20his%20cash%20in%20a%20bucket.%5CnBut%20his%20daughter%20named%20Nan%2C%5CnRan%20away%20with%20a%20man%5CnAnd%20as%20for%20the%20bucket%2C%20Nantucket.%22%7D)\n\nCount the *unique* words in the input:\n\n[`cat input.txt | pjs --before 'let words = new Set()' 'for (let word of $) words.add(word)' --after 'words.size'`](https://aduros.com/pjs/#%7B%22command%22%3A%22pjs%20--before%20'let%20words%20%3D%20new%20Set()'%20'for%20(let%20word%20of%20%24)%20words.add(word)'%20--after%20'words.size'%22%2C%22input%22%3A%22There%20once%20was%20a%20man%20from%20Nantucket%5CnWho%20kept%20all%20his%20cash%20in%20a%20bucket.%5CnBut%20his%20daughter%20named%20Nan%2C%5CnRan%20away%20with%20a%20man%5CnAnd%20as%20for%20the%20bucket%2C%20Nantucket.%22%7D)\n\nUsing a script file instead of command-line arguments:\n\n```sh\necho '\n    BEFORE: {\n        print(\"Starting up!\")\n    }\n    _.toUpperCase()\n    AFTER: \"Total lines: \"+COUNT\n' \u003e my-uppercase.js\n\ncat document.txt | pjs -f my-uppercase.js\n```\n\nAdding a shebang to the above script to make it self-executable:\n\n```sh\necho \"#!/usr/bin/env -S pjs -f\" | cat - my-uppercase.js \u003e my-uppercase\nchmod +x my-uppercase\n\n./my-uppercase document.txt\n```\n\nCompletely scrape an entire online store, outputting a JSON stream for later processing:\n\n```sh\nfor page in `seq 1 50`; do\n\n    \u003e\u00262 echo \"Scraping page $page...\"\n    curl -s \"http://books.toscrape.com/catalogue/page-$page.html\" |\n        pjs --html '.product_pod h3 a' '\"http://books.toscrape.com/catalogue/\"+_.attr.href' |\n\n        while read url; do\n            \u003e\u00262 echo \"Scraping item details from $url\"\n            curl -s \"$url\" | pjs --html '.product_page' 'JSON.stringify({\n                title: _.querySelector(\".product_main h1\").text,\n                description: _.querySelector(\"#product_description + p\").text})'\n        done\ndone\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faduros%2Fpjs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faduros%2Fpjs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faduros%2Fpjs/lists"}