Tiny Deathstars of Foulness

When you’re building and manipulating apps in the Apple App Stores, it helps to be able to pull and parse pieces of data. Here, we’ll look at two strategies that you can use to do so. It’s worth noting that the purpose of this was to use the URL of an app from an MDM and then be able to script updating metadata about the app, given that vendors often change names of the display name of an app (e.g. Yelp is actually called “Yelp: Discover Local Favorites on the App Store”).

First, we’ll grab a URL. This one is for Self Service:

If you don’t know the URL then you can get it based on the ID by parsing the json from:


Of course, if you know the id, you can probably just assume that will work as well, since if you remove the name it has always worked for me (although I’ve never seen that in a spec so I can’t guarantee it will always be true). Then, we can curl it, but the output is a bit not lovely:

curl -s ''

So then we’ll want to just grab the pieces of information we want, which could be done using a variety of scripting techniques. Below, we’ll use grep:

curl -s '' | grep -o "<title>[^<]*" | cut -d'>' -f2-

And here, we’ll use perl:

curl -s '' | perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si'

And there you go, you have the title. The title is easy, because it’s a simple title tag. But let’s look at the description:

curl -s '' | awk '/meta name="description"/{;print }'

The output would be similar to the following 

<meta name="description" content="Read reviews, compare customer ratings, see screenshots, and learn more about Self Service Mobile. Download Self Service Mobile and enjoy it on your iPhone, iPad, and iPod touch." id="ember75894226" class="ember-view">

From there it’s pretty simple to extract the exact field you want and the metadata from that field. If you are obtaining names and descriptions for a large number of apps then you’d simply move the path into a variable as follows so you can put it into your loop:

curl -s $appurl | grep -o "<title>[^<]*" | cut -d'>' -f2-

I haven’t covered finding items in the App Store if you don’t know the ID of an app, but there’s a /search endpoint at that will respond to a variety of parameters you can pass:


This wasn’t necessary for my use case. But it’s worth noting. And if you’ll be doing a lot of that, I’d recommend checking out the affiliates portal at Additionally, if you’re actually trying to automate the App Store instead, there are a few tools out there to do so, including or if you want to extract packages there’s

March 2nd, 2018

Posted In: Apple Configurator, Apps, iPhone, Mac OS X

Tags: , , , , , , , ,

One Comment

In the following example script, I’m going to pull a list of just the usernames from fdesetup. sudo fdesetup list The output would be as follows:
charlesedge,F4D8B61D-1234-1234-98F4-103470EE1234 emerald,2E1203EA-1234-4E0D-1234-717D27221234 admin,50058FCF-88DF-1234-1234-91FCF28C0488
I’ll then pipe them into sed and use the , as a delimiter, pulling * or everything before it: sudo fdesetup list | sed 's;,.*;;' As follows:
charlesedge emerald admin

August 29th, 2017

Posted In: bash, Mac OS X, Mac OS X Server

Tags: , , ,

There’s a macOS tool called AssetCacheLocatorUtil located at /usr/bin/AssetCacheLocatorUtil. The output is in… stderr. Because stderr is so fun to work with (note that sed -i only works with stdin). So, to update the caching server(s) you are using and only print the IP address of those, you’d do the following: /usr/bin/AssetCacheLocatorUtil 2>&1 | grep guid | awk '{print$4}' | sed 's/^\(.*\):.*$/\1/' | uniq If you use Jamf Pro and would like to use this as an extension attribute, that’s posted here: I didn’t do any of the if/then there, as I’d usually just do that on the JSS.

April 17th, 2017

Posted In: Mac OS X, Mac Security, Mass Deployment, Network Infrastructure, precache

Tags: , , , , , , , , , ,

You can leverage the API built into the Casper Suite to do lots and lots of cool stuff, without interacting directly with the database. Here, I’ll use a simple curl command in a bash script that has myuser as the username for a server and mypassword as the password. The server is Basically, we’re going to ask the computers and mobiledevices tables for all their datas. Once we have that, we’ll constrain the output to just the size attribute for each using sed: curl -s -u myuser:mypassword | sed -n -e 's/.*<size>\(.*\)<\/size>.*/\1/p' curl -s -u myuser:mypassword | sed -n -e 's/.*<size>\(.*\)<\/size>.*/\1/p' This same logic can then be applied to any payload of XML data coming out of a REST API. Some API’s have different options to constrain output of a request, some don’t. But no matter whether there is or isn’t, you can loop through a bunch of statements like this. Why would you look to the API to constrain data, etc? Well, it comes down to a cost issue. Each time you run the above commands, you’re costing yourself runtime, you’re taxing the server with potentially a substantial query, and you’re potentially transferring a considerable amount of data over the wires between you and where the script is being run. So if the API is smart enough to give you less data, then you might as well do that. In this case, it isn’t, but if you apply this same sed logic in other scripts, it’s great to be cognizant of remaining as efficient as you can.

December 18th, 2015

Posted In: JAMF

Tags: , , , , , , , , ,

The following command will remove all empty lines from a file called sed '/^$/d'

July 12th, 2015

Posted In: Mac OS X, Mac OS X Server, Ubuntu

Tags: , , , ,

I find a very common task that I need to do is find a string in a file and replace it with another string. Or better, find all instances of a given string and replace them with a new string. I figure others will need to do this as well. This is also an interesting example of how Mac OS X is not “the same” as Linux. The sed command can be used to quickly perform a find and replace inside of a file. The following example will use the -i option to do so in-place, defining no extensions to -i using the double quotes (“”), then using the /s to instruct a substitution of the pattern to match followed by the pattern to replace (in this case we’re finding like and replacing it with love in celebration of the upcoming Valentines Day) and doing so globally, or for all instances using the /g option. The find and replace will be performed inside of the file called /Users/krypted/test: sed -i "" 's/like/love/g' /Users/krypted/test Because things can go wrong during the edit, such as an OS crash, it is always smart to make a backup of your file before you change it. By appending a .backup to the -i option, sed will get instructed to make a backup: sed -i.backup -e 's/like/love/g' /Users/krypted/test By default in Linux, the command would work with or without the double quotes (“”) that I used to define the extension; however, as mentioned Mac OS X is not Linux; you have to define an extension or the command will error out. Overall, finding and replacing or substituting text within a file is a very common systems administration task and the above command is a very simplistic approach to performing such a task.

February 7th, 2011

Posted In: Mac OS X, Ubuntu

Tags: , , , , ,

Yesterday I showed a way to get the serial number from a Mac OS X machine. However, as a couple of people pointed out, Apple will soon be adding another character to the serial number. This means that rather than use cut I should have used awk to allow for either serial number length. To grab the serial this way:
ioreg -l | grep IOPlatformSerialNumber | awk ‘{print $4}’
Or without the quotes:
ioreg -l | grep IOPlatformSerialNumber | awk ‘{print $4}’ | sed ‘s/”//g’

May 13th, 2010

Posted In: Mac OS X, Mac OS X Server, Mass Deployment

Tags: , , ,

A number of commands available for finding positions that you want in a line and extracting only a certain amount of text can be pretty cumbersome in terms of learning curve. This isn’t to say that once you get the hang of them that they’re terribly complicated but it can take a little while to get the hang of them. And when you need something fast, you might want an easy command for extracting text from lines. In these cases, consider cut. The cut command doesn’t do regular expressions (I guess you could argue that its ability to use a delimiter can be used as a regular expression) and so it’s really easy to use. Basically, you feed cut some data and then tell it which characters in the line that you want to keep. It then gets rid of the rest. The easiest use of this is to look at a list of data. For example, let’s saw we have a file called test.txt with the following contents:
abc123 abc124 abc134 abc234 abd234 acd234
Now we’re going to cat the file (which just reads the file contents) and then pipe the output of reading that file into a cut command (which is done by simply adding a pipe character at the end of the first part of the command. Then we’re going to use the -c option of cut (which looks at character positions) to simply grab the first three positions (1-3) of the lines. The command would end up looking as follows:
cat test.txt | cut -c 1-3
And the output would look as follows (this output could then be redirected into a new file btw):
abc abc abc abc abd acd
You can also specify multiple ranges of characters (or single characters for that matter). For example, to see only characters 1-2 and 5-6:
cat test.txt | cut -c 1-2,5-6
Overall, cut is a very easy to use tool, with a limitation that your pattern that you are looking to maintain must be consistent in terms of the character position that you are using in each line. It also uses every line in a file; however, to go another step and look for all positions in a line only if the line has a pattern that it can match you could simply add a grep in the middle. For example, if you’re looking for each line of our sample text file that has the number 4 then you could do:
cat test.txt | grep 4
This would show you only the last five lines of the file since those are the only lines that have that number in them. You could then pipe the output of that file into your cut and, let’s say, look for characters 1-3 and 6 in the output:
cat test.txt | grep 4 | cut -c 1-3,6
Your result would then be the following:
abc4 abc4 abc4 abd4 acd4
Finally, there are going to be times when you’re not looking for a specific character position in a line but instead a character position or a pattern that begins with another pattern. For this you’re going to end up needing to use a more advanced tool, such as awk or if you’re feelin’ frisky (maybe I’m speaking for myself there) regex. These tools will have a steeper learning curve, but ultimately be far more useful.

January 17th, 2010

Posted In: Mac OS X, Mac OS X Server, Mac Security, Unix

Tags: , , , , , , , , ,

Add a comma to the end of every line of a file in bash:

sed 's/$/,/'

April 21st, 2005

Posted In: Mac OS X, Ubuntu, Unix

Tags: , ,