Summary
Welcome to part two of our Introduction to Scripting series! The series helps IT administrators build confidence with scripting and programming logic, highlights tools built into macOS, and introduces new techniques for more experienced script writers.
In Part 1, Introduction to Scripting: Build Confidence with Command-Line Tools in macOSwe covered:
- Locating the Terminal and System Information in macOS.
- Understanding system_profiler: Learn what it does, how to run it, and why it matters.
- Sending data to a text file.
- Finding documentation for command-line tools.
- Modifying commands using options or flags.
- Parsing output data to meet specific requirements.
Our Challenge
Throughout this series, we’ll explore a practical example and solve it using command-line tools built into macOS. We start with the basics and focus on the ideal path. Once the fundamentals work, we’ll add features, verification, and documentation as we encounter unexpected issues.
Here's our challenge: During a computer refresh across campus, we want to verify that displays meet a minimum screen resolution threshold. Our school uses many Mac mini computers in classrooms, labs, and shared spaces. These devices connect to various screens and projectors purchased from different vendors over many years.
We could walk to each room and check manually. Instead, we’ll use automation, which saves time now and remains useful for future refreshes.
Requirements for the Series
As in part 1, to follow along, gather the following hardware and software:
- Obtain a test Mac or virtual machine running macOS 15 or later. This serves as your primary test environment.
- Prepare a secondary test Mac or virtual machine running macOS 14. Later parts of the series require this.
- Connect a primary monitor if using a Mac without a built-in display.
- Connect a secondary monitor for use in later parts of the series.
- Create a test user with administrator permissions.
- Have the Terminal application available.
- Use TextEdit or another text editor capable of writing or editing scripts.
What You Will Learn
In this article, we’re going to take your knowledge to the next level. We will cover:
- Understanding the difference between pixels and resolution
- Parsing JSON with jq
- Manipulating text with awk
Resolution, Pixels, and Display Scaling
In Part 1, the Wrap Up and What's Next section included this note:
"Consider if there is a difference between resolution and pixels for display output. Does a Retina display output differ from a standard display?"
This question points to an important distinction. Some displays have a higher pixel count than the resolution being rendered. For example, when running system_profiler SPDisplaysDataType, the output may differ from what appears in System Settings. Open System Settings, go to Displays, and hover over the Default option. The value shown — such as 1440 x 900 — reflects the scaled resolution, not the full pixel count. Retina displays render a lower resolution across a higher pixel density, which produces a sharper image.
This behavior is common on devices with Retina displays, Pro Display XDR, or other high-pixel-density displays scaled in the Displays pane in System Settings.
This also reinforces a recommendation from Part 1:
"It is always a good idea to check your work with other tools. Using System Settings is a reliable way to confirm that a command-line tool returns the expected data."
The initial output from system_profiler may be accurate in some cases and incomplete in others. To get a more complete picture of display settings, explore the additional flags available for system_profiler. Run system_profiler -help and note the -xml and -json flags. Both XML and JSON present data in a machine-readable format. Try both flags with system_profiler SPDisplaysDataType and compare the output.
Learning Challenge
Before continuing, review both the XML and JSON responses for system_profiler SPDisplaysDataType. Consider the following:
- Which format is easier for a person to read? Which is easier for a computer to process?
- Based on what we know about searching for values, which format may be easier to query?
- Is one format faster to work with than the other?
- Did you find the pixel and resolution values? Were they the same or different on your device?
- How does changing the default text size in the Displays pane in System Settings affect the response?
System Profiler with JSON Output
Now that we have explored three output formats and a few different resolutions, we can simplify the approach. For the remainder of this post, we use JSON. JSON is less verbose than XML and uses a key-value pair format that is generally easier to read.
You can use XML instead, but parsing XML requires different commands that are not covered in this post.
Type the following command in Terminal:
system_profiler SPDisplaysDataType -json
The output below is from a MacBook Air (M1) with only a built-in display. In addition to the 2560 x 1600 pixel resolution, the output shows additional values such as 2880 x 1800 and 1440 x 900. The value 1440 x 900 reflects the scaled resolution — the best representation of what appears on the display. We will work with _spdisplays_resolution going forward, keeping in mind that some additional handling will be needed.
Benefits of using _spdisplays_resolution:
- Identify the resolution that users have configured for daily work
- Parse the value with precision, since it contains focused data (unlike spdisplays_pixelresolution, which mixes text and numbers)
- Discover how many users have scaled their display resolution
- Identify displays configured below the intended resolution
localadm@MacBook-Air ~ % system_profiler SPDisplaysDataType -json
{
"SPDisplaysDataType" : [
{
"_name" : "kHW_AppleM1Item",
"spdisplays_mtlgpufamilysupport" : "spdisplays_metal3",
"spdisplays_ndrvs" : [
{
"_name" : "Color LCD",
"_spdisplays_display-product-id" : "a047",
"_spdisplays_display-serial-number" : "fd626d62",
"_spdisplays_display-vendor-id" : "610",
"_spdisplays_display-week" : "0",
"_spdisplays_display-year" : "0",
"_spdisplays_displayID" : "1",
"_spdisplays_pixels" : "2880 x 1800",
"_spdisplays_resolution" : "1440 x 900 @ 60.00Hz",
"spdisplays_ambient_brightness" : "spdisplays_yes",
"spdisplays_connection_type" : "spdisplays_internal",
"spdisplays_display_type" : "spdisplays_built-in_retinaLCD",
"spdisplays_main" : "spdisplays_yes",
"spdisplays_mirror" : "spdisplays_off",
"spdisplays_online" : "spdisplays_yes",
"spdisplays_pixelresolution" : "spdisplays_2560x1600Retina"
}
],
"spdisplays_vendor" : "sppci_vendor_Apple",
"sppci_bus" : "spdisplays_builtin",
"sppci_cores" : "8",
"sppci_device_type" : "spdisplays_gpu",
"sppci_model" : "Apple M1"
}
]
}%
Parsing JSON with jq
Now that we can retrieve a resolution value that reflects the user's display configuration, we can extract the specific data from the output. The built-in tool jq makes it straightforward to parse JSON. Note that jq is available by default on macOS 15 and later. A future post will cover how to parse JSON on earlier versions of macOS.
To parse JSON, navigate the structure of the output step by step. Compare the following commands:
system_profiler SPDisplaysDataType -json | jq
system_profiler SPDisplaysDataType -json | jq '.SPDisplaysDataType'
system_profiler SPDisplaysDataType -json | jq '.SPDisplaysDataType[]'
Learning Challenge
Now that you have seen examples of how to structure jq queries, try to retrieve only the value of _spdisplays_resolution by extending the commands above. As you experiment, consider:
- What differences do you notice between these commands?
- How does the output change with each variation?
- What is the difference between [ ] and { }?
- Were you able to retrieve "1440 x 900 @ 60.00Hz" or a similar value on your device? If not, that is expected — multiple arrays and special characters add complexity at first.
The command to retrieve just the display resolution is:
system_profiler SPDisplaysDataType -json | jq '.SPDisplaysDataType[].spdisplays_ndrvs[]._spdisplays_resolution'
The value returned includes quotes, the display width, the display height, and the refresh rate. To focus on resolution, we can remove the quotes and the refresh rate in the steps below.
To remove the quotes from the output, add the -r flag to jq. Place the flag between jq and .SPDisplaysDataType. When placed correctly, the command returns the raw data without quotes.
Text Manipulation with awk
With quotes removed, the next step is to remove the refresh rate from the output. Several approaches are possible using tools covered in Part 1. In this post, we use awk.
awk can quickly parse strings using a print statement. Try the following command and note the output:
system_profiler SPDisplaysDataType -json | jq -r '.SPDisplaysDataType[].spdisplays_ndrvs[]._spdisplays_resolution' | awk '{print $1}'
What did you get? Try changing $1 to $2. From here, you can retrieve just the width and height of the screen resolution. Use the commands below to find each value separately, or combine print statements to return multiple values at once:
system_profiler SPDisplaysDataType -json | jq -r '.SPDisplaysDataType[].spdisplays_ndrvs[]._spdisplays_resolution' | awk '{print $1}'
system_profiler SPDisplaysDataType -json | jq -r '.SPDisplaysDataType[].spdisplays_ndrvs[]._spdisplays_resolution' | awk '{print $3}'
system_profiler SPDisplaysDataType -json | jq -r '.SPDisplaysDataType[].spdisplays_ndrvs[]._spdisplays_resolution' | awk '{print $1, $2, $3}'
Experiment with other variations to build familiarity and gather additional data.
Wrap Up and What's Next
And that’s it for Part 2 of our series! In the next post, we’ll build a script from the commands covered so far. The script will run in Apple Remote Desktop or your Device Management Service. In the meantime, experiment with jq, grep, and awk to explore more data from system_profiler. Feel free to comment below to share your learning and a-ha moments!

Attach up to 5 files which will be available for other members to download.