12 ms·
Why not parse `ls` and what to do instead
- jcalvinowens 2y agoNot sure how portable it is, but gnu ls has a flag to solve this problem trivially: --zero end each output line with NUL, not newline
- Aaron2222 2y agoNot available in macOS `ls` unfortunately.
- fellerts 2y agoThe title omits the final '?' which is important, because the rant and its replies didn't settle the matter. Shellcheck's page on parsing ls links to the article the author is nitpicking on, but it also links to the answer to "what to do instead": use find(1), unless you really can't. https://mywiki.wooledge.org/BashFAQ/020 https://mywiki.wooledge.org/BashFAQ/020
- noobermin 2y agoPosts like these are like the main character threads on twitter where someone says, "men don't do x" or "women aren't like y." It just feels like people outside of you who have no understanding of your context seem intent on making up rules for how you should code things. Perhaps it would help to translate this into something more like, "what pitfalls do you run into if you parse `ls`" but it's hard to get past the initial language.
- qsort 2y agoWhen we say "don't do X" we mean "the obvious way is wrong". If you have enough knowledge to ignore the advice, you likely are already aware of the problems with the obvious solution. I'm pretty sure you can come up with scenarios where parsing the output of "ls" is indeed the simplest solution, but that kind of article is supposed to discourage people who don't know better from going "oh, I know, I'll just parse the output of ls". As a general advice, people should indeed be pointed towards "man find" or "man opendir 3".
- g15jv2dp 2y agoWhat to do instead: use pwsh to completely obviate all these issues.
- Qwertious 2y agoOr, once it's API-stable, use nushell.
- DonHopkins 2y agoPython has had an API-stable module for listing directories for decades, you know.
- Aerbil313 2y agoDo you recommend it? I feel like I'd get RSI from pressing shift when using it. https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/?view=powershell-7.4 https://learn.microsoft.com/en-us/powershell/module/microsof...
- gfv 2y agoPowershell is mostly case-insensitive, and most of the core cmdlets have short aliases. Try `Get-Alias` (or `gal`) to learn more.
- shiandow 2y agoIt's case insensitive for what it's worth. My main problem is trying to figure out which utilities they've bundled into which command.
- g15jv2dp 2y agoYes, I absolutely recommend it. I use it every day. Commands and flags are case-insensitive.
- DonHopkins 2y agoIsn't it ironic that Powershell from Microsoft is so much vastly superior than bash, not because it's great or even better than Python, but because bash is such a terribly low bar to beat, that it totally undermines the "Unix Philosophy"? Who would have thought that little old Microsoft, purveyors of MSDOS CMD.EXE, would have leapfrogged Unix and come out with something so important and fundamental as a shell that was superior to all of Unix's "standard" sh/csh/bash/whatever shells in so many ways, all of which historically used to be and ridiculously still are touted by Unix Supremacists as one of its greatest strengths? You see, Microsoft is willing to look at the flaws in their own software, and the virtues of their competitors' software, then admit that they made mistakes, and their competitors did something right, and finally fix their own shit, unlike so many fanatical monolinguistic Unix evangelists. They did the exact same thing to Java and JavaScript, leaving Visual Basic and CMD.EXE behind in the dustbin of history -- just like Unix should leave bash behind -- resulting in great cross platform languages like C# and TypeScript. Edit: that reinforces my point that taking so long to get there is a hell of a lot better than taking MUCH LONGER to NOT get there. Maybe bash's legacy inertia is a problem, not a virtue. Is certainly isn't getting a JSON parser in the foreseeable future. The ironic point is that even Microsoft's power shell has much less legacy inertia, and therefore is so much better, in such a shorter amount of time.
- hawski 2y agoI think that when someone uses ls instead of a glob it means they most probably don't understand shell. I don't see any advantage of parsing ls output when glob is available. Shell is finicky enough to not invite more trouble. Same with word splitting, one of the reasons to use shell functions, because then you have "$@" which makes sense and any other way to do it is something I can't comprehend. Maybe I also don't understand shell, but as it was said before: when in doubt switch to a better defined language. Thank heavens for awk.
- DonHopkins 2y agoWhen you don't want to waste your time and sanity and happiness being in doubt and then throwing away all you've done and switching to a new language in mid stream, just don't even start using a terribly crippled shell scripting language in the first place, also and especially including awk. The tired old "stick to bash because it's already installed everywhere" argument is just as weak and misleading and pernicious as the "stick to Internet Explorer because it's already installed everywhere" argument. It's not like it isn't trivial to install Python on any system you'll encounter, unless you're programming an Analytical Engine or Jacquard Loom with punched cards.
- cassianoleal 2y agoIn most places where I run shell scripts, there is no Python. There could be if I really wanted it but it's generally unnecessary waste. On top of it, shell is better than Python for many things, not to mention faster. It's also, as you mentioned, ubiquitous. In the end, choose the tool that makes more sense. For me, a lot of the time, that's a shell script. Other times it may be Python, or Go, or Ruby, or any of the other tools in the box.
- DonHopkins 2y agoA waste of what, disk space? I'd much rather waste a few megabytes of disk space than hours or days of my time, which is much more precious. And what are you doing on those servers, anyway? Installing huge amounts of software, I bet. So install a little more! For decades, on most Windows computers I run web browsers, there's always Internet Explorer. So do you still always use IE because installing Chrome is "wasteful"? It's a hell of a lot bigger and more wasteful than Python. As I already said, that is a weak and misleading and pernicious argument. So what exactly is bash better than Python at, besides just starting up, which only matters if you write millions of little bash and awk and sed and find and tr and jq and curl scripts that all call each other, because none of them are powerful or integrated enough to solve the problem on their own. Bash forces you to represent everything as strings, parsing and serializing and re-parsing them again and again. Even something as simple as manipulating json requires forking off a ridiculous number of processes, and parsing and serializing the JSON again and again, instead of simply keeping and manipulating it as efficient native data structures. It makes absolutely no sense to choose a tool that you know is going to hit the wall soon, so you have to throw out everything you've done and rewrite it in another language. And you don't seem to realize that when you're duct-taping together all these other half-assed languages with their quirky non-standard incompatible byzantine flourishes of command line parameters and weak antique domain specific languages, like find, awk, sed, jq, curl, etc, you're ping-ponging between many different inadequate half-assed languages, and paying the price for starting up and shutting down each of their interpreters many times over, and serializing and deserializing and escaping and unescaping their command line parameters, stdin, and stdout, which totally blows away bash's quick start-up advantage. You're arguing for learning and cobbling together a dozen or so different half-assed languages and flimsy tools, none of which you can also use to do general purpose programming, user interfaces, machine learning, web servers and clients, etc. Why learn the quirks and limitations of all those shitty complex tools, and pay the cognitive price and resource overhead of stringing them all together, when you can simply learn one tool that can do all of that much more efficiently in one process, without any quirks and limitations and duct tape, and is much easier to debug and maintain?
- amelius 2y agoI feel like Unix utilities should provide a standardized way to generate machine-readable output, perhaps using JSON.
- db48x 2y agoThe same information is already available in a machine–readable format. Just call readdir. You don’t need to run ls, have ls call readdir and convert the output into JSON, and then finally parse the JSON back into a data structure. You can just call readdir!
- masklinn 2y ago`find` is also an option, or shell globs.
- db48x 2y agoRight, globs are syntactic sugar on top of readdir. Definitely use them when you are in a shell. But in general the solution is to call readdir, or some language facility built directly on top of it. Calling ls and asking it for JSON is the stupid way to do things.
- amelius 2y agoJust curious, how would you approach getting output from utilities like "df", "mount" and "parted"?
- solardev 2y agoGenerally speaking, can't you limit/define the output of those commands and parse them that way? like df --portability or --total or --output And/or use their return codes to verify that something worked or didn't Or hope your higher level programming language contains built-ins for file system manipulations
- 2y ago
- Aerbil313 2y agoWhat to do instead: Use Nushell. I finally started really using my shell after switching to it. I casually write multiple scripts and small functions per day to automate my stuff. I'm writing scripts I'd otherwise write in python in nu. All because the data needs no parsing. I'm not even annotating my data with types even though Nushell supports it because it turns out structured data with inferred types is more than you need day-to-day. I'm not even talking about all the other nice features other shells simply don't have. See this custom command definiton: # A greeting command that can greet the caller def greet [ name: string # The name of the person to greet --age (-a): int # The age of the person ] { [$name $age] } Here's the auto-generated output when you run `help greet`: A greeting command that can greet the caller Usage: > greet <name> {flags} Parameters: <name> The name of the person to greet Flags: -h, --help: Display this help message -a, --age <integer>: The age of the person It's one of the software that only empowers you, immediately, without a single downside. Except the time spent learning it, but that was about a week for me. Bash or fish is there if I ever need it to paste some shell commands.
- db48x 2y agoParsing, or the lack thereof, is not the point. The point is that standard shells already provide all the tools you need for dealing with lists of files. Want to do something for every file? Write this: shopt -s nullglob for f in *; do … done But never this: for f in $(ls); do … done They look similar, but the latter runs ls to turn the list of files into a string, then has the shell parse the string back into a list. Even if the parsing was done correctly (and it isn’t), this is still extra work. Looping over the glob avoids the extra work.
- Aerbil313 2y agoI have to say this is very unintuitive. In Nushell, you'd do: ls | each { ... } Another examples I don't need to explain, which would be far harder in stringly typed shells: ls | where type == file and size <= 5MiB | sort-by size | reverse | first 10 ps | where cpu > 10 and mem > 1GB | kill $in.pid It's immediately obvious what you need to do when you can easily visualize your data: > ls ╭────┬───────────────────────┬──────┬───────────┬─────────────╮ │ # │ name │ type │ size │ modified │ ├────┼───────────────────────┼──────┼───────────┼─────────────┤ │ 0 │ 404.html │ file │ 429 B │ 3 days ago │ │ 1 │ CONTRIBUTING.md │ file │ 955 B │ 8 mins ago │ │ 2 │ Gemfile │ file │ 1.1 KiB │ 3 days ago │ │ 3 │ Gemfile.lock │ file │ 6.9 KiB │ 3 days ago │ │ 4 │ LICENSE │ file │ 1.1 KiB │ 3 days ago │ │ 5 │ README.md │ file │ 213 B │ 3 days ago │ ...
- probably_wrong 2y agoI think there's a middle point where you want to do something that's complex enough that a glob won't cut it but simple enough that switching languages is not worth it. I think the example of "exclude these two types of files" is a good case. I often have to write stuff like `ls P* | grep -Ev "wav|draft"` which doesn't solve a problem I don't have (such as filenames with newlines in them) but does solve the one I do (keeping a subset of files that would be tricky to glob properly). In my experience 95% of those scripts are going to be discarded in a week, and bringing Python into it means I need to deal with `os.path` and `subprocess.run`. My rule of thumb: if it's not going to be version controlled then Bash is fine.
- deleted 2y ago[deleted]
- OrderlyTiamat 2y agoYou might enjoy a variety of `find` based commands, e.g. `find -maxdepth 1 -iregex ".*\.(wav|draft)" | xargs echo "found file:"` This uses regex to match files ending in .wav or .draft (which is what I interpreted you to want). Xargs then processes the file. You could use flags to have xargs pass the file names in a specific place in the command, which can even be a one liner shell call or some script. So the "find <regex> - xarg <command>" pattern is almost fully generally applicable to any problem where you want to execute a oneliner on a number of files with regular names. (I think gnu find has no extended regex, which is just as well- thats not a "regular expression" at that point)
- bheadmaster 2y ago> You might enjoy a variety of `find` based commands, e.g. `find -maxdepth 1 -iregex ".*\.(wav|draft)" | xargs echo "found file:"` Find can even execute commands itself without using `xargs`: find -maxdepth 1 -iregex '.\.\(wav\|draft\)' -exec echo "found file:" {} \;
- Izkata 2y agoDefinitely do it this way if you want to stick to the pre-filtered version (I recommend the cousin comment, filter inside the loop). GP's version is buggy in the same way as the post misunderstands, particularly with files that somehow got newlines in the filename (xargs is newline-delimited by default). If for some reason you do need the "find | xargs" combo (maybe for concurrency), you can get it to work with "find -print0" and "xargs -0". Nulls can't be in filenames so a null-delimited list should work.
- deleted 2y ago[deleted]
- mcc1ane 2y agohttps://mywiki.wooledge.org/BashPitfalls#for_f_in_.24.28ls_.2A.mp3.29 https://mywiki.wooledge.org/BashPitfalls#for_f_in_.24.28ls_....
- teddyh 2y agoMany people turn to globbing to save them, which is usually better, but has some problems in case of no matches. But, for Bash, you can do this to fix it: shopt -s failglob
- billpg 2y agoWhy do you want to put LF bytes into filenames? Using magic, I've renamed any files you have to remove control characters in the name and made it impossible to make any new ones. (You can thank me later.) What can't you do now?
- tredre3 2y agoPreventing certain characters in filenames would solve a lot of issues, from security issues to wasted time all around. But for whatever reason, when it is suggested, you get many people chiming in that "filenames should be dumb bytes, anything allowed except / !"
- hifromwork 2y ago>But for whatever reason, when it is suggested, you get many people chiming in that "filenames should be dumb bytes, anything allowed except / !" I guess the issue is not what filenames should be, but what filenames are. In general, when interacting with files, you have to expect everything but `/` and nullbyte. Even if you forbid it on your machine, someone may mount a NFS drive and open you to the world of weird filenames. And you never know who uses your code. And the unicode itself is weird anyway - for example you may have normalised and denormalised names which may be the same or different string depending on how you look at them[1]. And I hope you are not planning to restrict filenames to some anglocentric [a-z0-9_- ]*, because the world is much larger and you can't pretend unicode doesn't exist. [1] https://eclecticlight.co/2017/04/06/apfs-is-currently-unusable-with-most-non-english-languages/ https://eclecticlight.co/2017/04/06/apfs-is-currently-unusab... and many other cases
- arp242 2y agoLatest POSIX "encourages" implementations to forbid using newlines in pathnames. https://austingroupbugs.net/view.php?id=251 https://austingroupbugs.net/view.php?id=251
- dTal 2y agoI've put a file in my home directory named the entirety of your comment, newline included. Unfortunately I had to trim "except / !" to bring it to 255 characters. Now at least when some tool or pipeline blows up horribly, it'll be hilarious.
- badgersnake 2y ago[flagged]
- solardev 2y agoBut hey, at least it's not YAML!
- emmelaich 2y agoThe funny thing is that so so many bits of info come in very much like but not quite yaml. e.g. /proc/cpuinfo
- badgersnake 2y agoOf course, with some k8s yaml we can run all our cli tools in separate containers each with their own userland.
- lukan 2y agoI do not think parsing json requires a full blown javascript engine.
- badgersnake 2y agoNeither does a graphical front end but that’s never stopped them.
- lukan 2y agoJust out of curiosity, what would be your proposal to use instead?
- afiori 2y agosadly JSON does not handle non-utf8 strings
- scintill76 2y agoIs that a problem for this application, though? Don’t most people encode their file names in utf8, or is that an ASCII-centric falsehood?
- badsectoracula 2y agoI guess this is for shell scripts that need to work with "unsafe" filenames? I've been using Linux since 1999 and i never came across a filename with newlines. On the other hand, pretty much all "ls parsing" i've done was on the command-line to pipe it to other stuff in files i was 100.1% sure would be fine.
- kemitchell 2y agoWhen teaching beginners shell, it's natural to teach `ls` for listing directory contents. It's also natural to extend from `ls` to `ls | ...` for processing lists of files The important point to get across is that pipes let us build bigger commands from the commands we already know. If needed, you can back up later to teach patterns like `find [...] -exec`, `find [...] -print0 | xargs -0 [...]`, `find [...] | while read -r file; do [...] done` and so on. There are all kinds of prerequisites to creating files with unusual names. Those barriers tend to mean beginners won't run into file name processing edge cases for a while. The exception will be files they download from the Internet. But the complexity there will usually be quote and non-ASCII Unicode characters, not newlines or other control codes. In teaching, the one filename complexity I would try to get ahead of, preventively, is spaces. There was a time, way back when, when newbies seemed to expect to stick with short, simple filenames. These days they the people I've helped tended to be used to using spaces in file names in Finder and Explorer for office or school work.
- zokier 2y agoI wonder if anyone has implemented kernel module or smth to limit filenames to sane set. Just ensuring that they are valid utf8 and do not contain any non-printables would be huge improvement. Sure some niche applications might break so its not something that can be made default, but still I think it would help on systems I control.
- tmtvl 2y agoToday I learned how neat find is: find ~/Music -iname 'p*' -not -iname '*age*' -not -iname '*etto*' find ~/Music -iname 'p*' -not -iregex '.*\(age\|etto\).*' find ~/Music -regextype posix-extended -iname 'p*' -not -iregex '.*(age|etto).*' Not that I'm likely to ever use any of that in anger, but it's good to know if ever I do wind up needing it.
- InsideOutSanta 2y agoFiles and directories, once a reference to them is obtained, should not be identified by their path. This causes all kinds of problems, like the reference breaking when the user moves or renames things, and issues like the ones described in the article, where some "edge case" (and I'm using that term very loosely, because it includes common situations like a space in a file name) causes problems down the line. You might say that people don't move or rename things while files are open, but they absolutely do, and it absolutely breaks things. Even something as simple as starting to copy a directory in Explorer to a different drive, and then moving it while the copy is ongoing, doesn't work. That's pathetic! There is no technical reason this should not be possible. And who can forget the case where an Apple installer deleted people's hard disk contents when they had two drives, one with a space character, and another one whose name was the string before the first drive's space character? Files and directories need to have a unique ID, and references to files need to be that ID, not their path, in almost all cases. MFS got that right in 1984, it's insane that we have failed to properly replicate this simple concept ever since, and actually gone backwards in systems like Mac OS X, which used to work correctly, and now no longer consistently do.
- Kwpolska 2y agoIDs don't really solve many problems. The issues with scripts removing all your files were either caused by the absurd bash spaces and quotes rules, or by bash silently ignoring nonexistent variables. Those scripts would still need paths, since the ID of ~/.steam will be different for everyone. Scripts that need to work on more than one system, and human-authored config files, would still have paths. There are cases where you want to depend on the path, not the identity of the folder, and potentially swap the folder with something else without editing configuration. Explorer needs to support local drives, with a lot of filesystems, including possibly third-party ones, but also network drives, FTP, WebDAV, and a bunch of other niche things. Not all of them have IDs and might not be possible to be extended. The cost is massive, solving it everywhere is impossible, and the benefit seems negligible to me (even though I fairly recently managed to eject a disk image (vhdx) in the middle of copying files onto it…)
- InsideOutSanta 2y ago
- 7bit 2y agoOr use PowerShell where LS returns a bunch of objects, and say goodbye to string parsing forever.
- chickenimprint 2y agonushell is the superior structured data shell and it's cross-platform. https://www.nushell.sh/ https://www.nushell.sh/
- redserk 2y agoI've only used Powershell a little bit on Linux and Mac but it seems reasonably cross-platform. On the surface, it looks like I'd be giving up the decently sized ecosystem of Powershell libraries for a new ecosystem without much support? I'm interested in knowing what Nushell does differently since I'm wanting to find a better shell.
- ericfrederich 2y agoWait until you realize that "giving up the decently sized ecosystem of Powershell libraries" is a net positive ;-)
- chickenimprint 2y agoI'm probably not the best person to ask, since the last time I touched Powershell, it was Windows only, but I'd say nushell is likely a lot more platform-agnostic, has sane syntax and follows a functional paradigm. Plugins are written in Rust. It's probably not worth it if all you do is Windows sysadmin work, as you'd have to serialize and deserialize data when interacting with Powershell from nu.
- TristanBall 2y agoLast I looked, powershell's startup time on linux was disappointing. Understandable to an extent given it was bootstrapping a bunch of dotNET stuff that would already be there on windows. But slow enough that I couldn't use or recommend it to my team.
- 2y ago
- TacticalCoder 2y agoNow of course having scripts and pre-commit hooks enforcing simple rules so that files must only use a subset of Unicode are a thing and do help. Do you really think that, say, all music streaming services are storing their songs with names allowing Unicode HANGUL fillers and control characters allowing to modify the direction of characters? Or... Maybe just maybe that Unicode characters belong to metadata and that a strict rule of "only visible ASCII chars are allowed and nothing else or you're fired" does make sense. I'm not saying you always have control on every single filename you'll ever encounter. But when you've got power over that and can enforce saner rules, sometimes it's a good idea to use it. You'll thank me later.
- renewiltord 2y agoI just solve this by not having files like that on my computer. No spaces. No null chars.
- hifromwork 2y agoMicrosoft famously named "Documents and Settings" folder that way to defeat developers like you :). Anyway check it, you might find you have files with spaces after all. For me it's: * /boot/System Volume Information * /proc/irq/126/PCIe PME * /sys/bus/platform/drivers/int3403 thermal * /etc/NetworkManager/system-connections/Hotel Xxx.nmconnection * /home/xxx/.cache/chromium/Default/Code Cache * and many others.
- renewiltord 2y agoThis is great. I `del mydocu~1` to kingdom come! Thank you. I meant in my home dir. I would never dare to presume anything about the rest. But it looks like Google demands that I be good at my job too.
- waffletower 2y agoBorkdude has a wonderful Clojure/Babashka solution in this space: https://github.com/babashka/fs https://github.com/babashka/fs
- geophile 2y agoI wrote a pipe-objects-instead-of-strings shell: https://marceltheshell.org https://marceltheshell.org. Not piping strings avoids this issue completely. Marcel’s ls produces a stream of File objects, which can be processed without worrying about whitespace, EOL, etc. In general, this approach avoids parsing the output of any command. You always get a stream of Python values.
- fooker 2y ago> In general, this approach avoids parsing the output of any command. Somewhere, there has to be validation phases. Just because you have objects, doesn't mean they are well formed. https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/ https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-va... It turns out proper validation is way harder than parsing. There is a reason text based interfaces and formats are so pervasive.
- geophile 2y agoAs long as Python does the right thing with globs, there is really no room for marcel to get it wrong. Not sure what additional validation you are thinking of.
- fooker 2y agoSuppose you store the result somewhere and then want to use it afterwards. How do you check if they are still valid files?
- geophile 2y agoThe File object encapsulates a path. If you use it, e.g. to read contents, and the file doesn't exist, then it will fail with an appropriate error message. Files come and go. References to them go stale. Every user and tool deals with this. This isn't a "validation" issue.
- lostmsu 2y agoThis is a problem I faced recently on Linux. You can use ip addr to see the list of your IPv6 addresses and their types (temporary or not, etc). But doing it programmatically from a non-C codebase is way more involved.
- Nimitz14 2y agoThese sorts of pedantic exchanges are so pointless to me. We are programmers. We can control what characters are used in filenames. Then you can use the simplest tool for the job and move on with your life to focus on the stuff that actually matters. Fix the root cause instead of creating workarounds for the symptom.
- tremon 2y agoMost of the time I avoid parsing ls, but I haven't found a reliable way to do this one: latest="$(ls -1 $pattern | sort --reverse --version-sort | head -1)" Anyone got a better solution?
- chenxiaolong 2y agoThis should work with any arbitrary filename: latest=$(printf '%s\0' <glob> | sort -zrV | head -zn1) or with long args: latest=$(printf '%s\0' <glob> | sort --zero-terminated --reverse --version-sort | head --zero-terminated --lines 1
- genrilz 2y agoWhat unix is this on? Neither the mac nor gnu manpages have a -z or --zero-terminated option for head.
- tremon 2y agoDebian's head (from GNU coreutils) does: https://manpages.debian.org/bookworm/coreutils/head.1.en.html https://manpages.debian.org/bookworm/coreutils/head.1.en.htm...
- genrilz 2y agoYay! Glad to see zero termination flags in more places. EDIT: The linux manpages I read were from die.net, which it looks like were from 2010, guess I'll have to avoid them in the future. I checked FreeBSD, OpenBSD, and Mac man page to make sure, and unfortunately none of them support the -z flag yet.
- genrilz 2y agoThis ones a hard one. Since "--version-sort" isn't standard anyways, lets assume we can use flags which are common to BSD and GNU. Furthermore, lets assume bash or zsh so we can use "read -d ''". In that case, how about: IFS='' read -d '' latest < <(find $pattern -prune -print0 | sort -z --reverse --version-sort)
- midjji 2y agoThe bash code which creates the c file which gets the list of null terminated files in a directory and compiles it, and runs it, is easier to write and understand. Bash is a lousy language to do anything in, python is almost always available, and if not, then CC is.
- cess11 2y agoI don't know, this seems like a lot of words to avoid coming to the conclusion that there are many ways to skin a directory. Most of the time it's fine to just suck in ls and split it on \n and iterate away, which I do a lot because it's just a nice and simple way forward when names are well-formed. Sometimes it's nicer to figure out a 'find at-place thing -exec do-the-stuff {} \;'. And sometimes one needs some other tool that scours the file system directly and doesn't choke on absolutely bizarre file names and gives a representation that doesn't explode in the subsequent context, whatever that may be, which is quite rare. A more common issue than file names consisting of line breaks is unclean encodings, non-UTF-8 text that seeps in from lesser operating systems. Renaming makes the problem go away, so one should absolutely do that and then crude techniques are likely very viable again.
- Tempest1981 2y agoRecent discussion about the original "don't parse" page being referenced: https://news.ycombinator.com/item?id=40692698 https://news.ycombinator.com/item?id=40692698 (10 days ago, 83 comments)
- bandie91 2y agoi searched through the page and have not found `find ... -printf "%M %n %u %g %s ...\0"` mentioned. this way you get ls(1)-like output, yet machine-parseable.