Bingo. It involved a little witchcraft piping two ogr2ogr instructions together via STDIN/OUT, and you'll need to adapt it to your purposes, but something like this should work:
ogr2ogr -f "GeoJSON" /vsistdout/ -dialect sqlite -sql " SELECT fullname, COUNT(*) as ct FROM ROADS_3857 GROUP BY fullname " "C:\xGIS\Vector\ROADS_3857.shp" | ogr2ogr -f "CSV" -where "ct=1" /vsistdout/ /vsistdin/ >"C:\xGIS\Vector\ROADS_3857_shpreport.txt"
This pumps out a file called "ROADS_3857_shpreport.txt" in the same directory as the initial
.shp source. The data in the file looks like this:
.. truncated ..
Casterton Dr E,1
Casterton Dr W,1
Castle Hall Ln,1
.. truncated ..
Here's the basic thinking.. the first ogr2ogr call does the work of an inner select, using OGR SQL to create the count value you need (named
ct in my example) and impose the GROUP BY, which it pushes to STDOUT (as GeoJSON, more on that in a bit) per the
/vsistdout/ flag where the data output path would normally go. Next, the pipe
| signals a second ogr2ogr call, which receives the initial result set via STDIN (note
/vsistdin/ flag in the data input path) and applies a simple
-where argument to return only the records with a count value of "1", once again pushing the final result to STDOUT by setting the output path to
/vsistdout/ in order to write it into a .txt file like you implied in your question.
I should probably explain why I used
-f "GeoJSON" and
-f "CSV" as the two output formats. First, apparently ogr2ogr's willingness to push various data formats over
/vsistdout/ is "hard to know", and I didn't find anything solid Googling the question. Additionally, ogr2ogr's willingness to receive various formats over
/vsistdin/ is equally mysterious. So refusing to believe this was impossible, I just experimented pushing one format through
/vsistdout/ and receiving it over
/vsistin/ until I found a combination that worked---that's how I arrived at GeoJSON and CSV, respectively. There wasn't any compelling logic there. :) The ogr data model deep in the guts of all this keeps things intact, so it doesn't really matter which driver formats we use to shuttle the data around in the middle, as long as they play well together over SDTIN/STDOUT.
It's equally important to mention that, if you wanted, you could replace the
/vsistout/ in the second ogr2ogr instruction with any export output format ogr2ogr supports, such as shapefile, MySQL, PostGRESql, etc. But to stay true to your initial question, I used
/vsistdout/ again in order to push it to the logfile.
That pretty much explains things--it just required approaching it a little differently. And again, I'm sure this will need to be tweaked to fit your exact case as I worked with a similar dataset that had different field names, etc. But I think this represents a good starting point to get where you want to go.