4 ms·
That's completely orthogonal. GNU bash has nothing to do with what arguments you can pass to GNU ls. You could use bash to run notepad.exe just as you could use
by milesrout 10y ago
That's completely orthogonal. GNU bash has nothing to do with what arguments you can pass to GNU ls. You could use bash to run notepad.exe just as you could use Powershell to run GNU ls.
If that's not the case, if Powershell actually does integrate most of what are on Unix-like systems separate commands, then that's terrible.
>Meanwhile, Unix commands are shorter, yes, but it's a lot more difficult for me to remember, e.g. that if I want to run a command across a number of files, I have to pass the command to find.
You don't have to do anything of the sort. If you want to run things across a number of files, you need a list of those files, and you need to know what you want to run across them. That list of files can come from anywhere. Does it come from a text file? A script? Or find? Doesn't matter.
If you do get them from find, you run things on them in precisely the same way you run things on any other list of files: a for loop.
for file in $(find ...); do
rm $file
done
Yeah you can also do
find ... -exec rm {} \;
or
find ... -print0 | xargs -0 rm
or any other number of other ways of doing it. But you don't have to. I'd probably use xargs to delete those files, honestly.
- BlackFingolfin 10y agoOf course one any of those filenames contains a space, your first two examples break down, and in the worst case result in the wrong files being deleted. Of course one can work around that, but in reality, this quickly gets difficult, and often is forgotten. The print0 works for some cases, but not in general (e.g. when one needs to do more complex processing)
- leni536 10y agoThe second example is fine, to be fair. {} is replaced by a single argument, no shell magic here.
- milesrout 10y agoThe second one doesn't fail, and the first one only fails because I wrote `rm $file` instead of `rm "$file"`, which I have done every single other time I've written the same thing this century.
- uzoodoo 10y agoWriting in first one won't save you since "in" splits by whitespace, not newline. If you really have to do that, use "find ... | while read file; do" instead.
- leni536 10y agoYour first example breaks for filenames containing whitespace.
- milesrout 10y agoFilenames containing whitespace are, and always have been, a bloody stupid idea.
- rocqua 10y agoNo, assuming filenames dont have whitespace is an idea that has fucked over people for a long time. Sure, it's annoying in a shell when whitespace is used as a separator but that seems more of an issue with shells than with filenames. Filenames should describe the file. In language, descriptions quite often require whitespace.
- milesrout 10y agoWhitespace should have been banned from filenames decades ago. If you need 'whitespace', use a hyphen or an underscore.
- oneeyedpigeon 10y agoI agree, if you ever want whitespace to have any special meaning in your shell (and you do), allowing spaces within filenames just causes no end of headaches.
- ygra 10y agoFor interactive use, tab completion already takes care of the escaping. For anything else the actual headache is that things are passed around as strings and command argument parsing is done for the expanded string where spaces can cause different argument parsing unexpectedly. This is certainly not limited to filenames but any argument that can contain spaces and is passed to a different command without proper quoting. The very fact that it's so easy to get wrong is perhaps a sign that things are a bit broken. But not necessarily at the filesystem level ...
- flukus 10y ago> That list of files can come from anywhere. Does it come from a text file? A script? Or find? Doesn't matter. This is an important concept. A powershell script might need to change depending on the source, sometimes it'll be a file object and other times a string, in unix it will always be a string. This is important for composability.
- vertex-four 10y agoIn practice, I seem to end up with a `sed` or `perl` script to mangle one string format into another between processes anyway. And then it all breaks between systems because half the most common commands have different defaults between systems. You can't even encode lists of strings in a format that's reliably understood by all UNIX programs.
- efaref 10y agoBetter: find ... -delete
- vram22 10y agoNice. Also: >If you do get them from find, you run things on them in precisely the same way you run things on any other list of files: a for loop. for file in $(find ...); do rm $file done If you know the number of files (and hence total command line length) will not be too high (i.e. not exceed the maximum length of a Unix command-line [1]), and that the filenames will not contain spaces or other problem-causing characters, you can shorten that to: rm $(find ...) # or rm -i $(find ...) for interactive deletion. This will only run rm once, instead of once for each file. If either or both of the above conditions are not met, your 2nd or 3rd snippets are preferable. [1] IIRC, there is a constant defined for that maximum, somewhere in standard C library's header files (maybe something like BUFMAX). I've read that early versions of Unix commands used to crash in some way (core dump or seg fault) if the length was exceeded, and seen that a few times myself. Also may have read that it was quite short initially, like 512 or 1024 bytes. People might have done something to fix that, apart from xargs, later. Update: I googled for this phrase: maximum length of unix command line and looked at the first few hits; found some info: xargs --show-limits can give info about the maximum length, which POSIX calls ARGMAX, not BUFMAX as I said above. and a sample output of xargs --show-limits is: Your environment variables take up 2446 bytes POSIX upper limit on argument length (this system): 2092658 POSIX smallest allowable upper limit on argument length (all systems): 4096 Maximum length of command we could actually use: 2090212 Size of command buffer we are actually using: 131072 There is no limit per argument, but a total for the whole command line length. In my system (Fedora 15/zsh) its closer to 2Mb. (line 4). (from http://stackoverflow.com/questions/6846263/maximum-length-of-command-line-argument-that-can-be-passed-to-sqlplus-from-lin http://stackoverflow.com/questions/6846263/maximum-length-of... ) One of the hits also says that getconf ARGMAX shows the value, on POSIX-conformant systems.