How to delete a file whose name begin with -

Yes. I can read that. With more effort old saxon. I do not know if old low frankish.
Ok, well I assumed you couldn't because the majority of people don't regularly read old texts. But if you do understand it you should be able to understand it's quite different from modern German because the German language evolved over time. English is an even weirder language because it's basically three or four different languages rolled into one which then got influenced by a lot of other European languages (including but not limited to the Romance and Latin languages). And in modern times even American English and British English are slightly different, not only in spelling (color vs. colour for example) but also in words and meaning (trainers vs. sneakers).
 
But if you do understand it you should be able to understand it's quite different from modern German because the German language evolved over time.
I have the impression that the oldest traded big text, old german tatian, is the easiest to read. Of course
it is a german column and a latin column, it is a known text (gospel harmony), but also its dialect, ostfränkisch,
helps. And Notker, alemannisch, is much easier to understand than modern swiss german. But yes, one needs
from time to time a dictionary, one must know a little of the gramar.
 
Hi SirDice, scottro,

could you please clarify what is the problem with a filename/folder with a space at the end? I would like to clean files inherited from Windows machine, with spaces both at the end and within the filename. To test deletion/renaming, I created - as a user - a file, a filename of which ends with space, and had no problem to delete it or rename ( mv) it.

Kindest regards,

M
 
Your strong opinions are always based on right understanding, because you always understand things right
and your understanding will never appear later to be wrong.
You can't be offended when you're wrong and confronted with the facts or it falls on you.
 
You can't be offended when you're wrong and confronted with the facts or it falls on you.
I do not understand what you mean. Perhaps you did not understand the context?

If the last is true, what would you think if someone reproaches you of having said the above strong opinion
being wrong about your understanding of the context?

That was exactly the context. Omniscient people was reproaching me not being omniscient as they are.

The issue of the facts became clear almost at the beginning of this thread. More clarity brought later
only ralfbsz. I was and am not offended, only amused of the computer scientific bigotry.

Well, perhaps you understand now that you did not understand the context. But as you said your "strong
opinion", you did not know it. You learn, hence you are also not omniscient.
 
Well, perhaps you understand now that you did not understand the context. But as you said your "strong
opinion", you did not know it. You learn, hence you are also not omniscient.
Well perhaps you didn't understand what I meant.

I meant that when you're wrong and bitch about being confronted with the facts it's you that looks the part.
 
I meant that when you're wrong and bitch about being confronted with the facts it's you that looks the part.
I still do not understand. I have absolute no problem of being confronted with the facts. It is absolutely no
offense. The essence of a dialog is contradiction: thesis–antithesis-synthesis.

Or were you only enunciating a general principle, just so, out of the blue?
 
could you please clarify what is the problem with a filename/folder with a space at the end?
I'm not the people you asked, but here are the two problems I experience.

First, confusion. Imagine I create two files, one named "a", the other named "aspace". I do ls, I see two files, both look like their names are just a. That can't be, there can't be two files with the same name! Or I create three files, named "a", "b", and "space". I do ls, all I see is two files.

The other problem is in scripts: when parsing script lines (which are after all just clear text, where strings are mixed with key words and values), file names with spaces get parsed as two separate words. Try this (in an empty directory), and I'm using sh/bash syntax for loops (not csh/tcsh syntax), and ">" is the shell prompt:
Code:
> touch a b "c d"
# You have created three files: "a", "b", and "c d"

stat -r *
16777221 91145641 0100644 1 568476 89939 0 0 1616905731 1616905731 1616905731 1616905731 4096 0 0 a
16777221 91145642 0100644 1 568476 89939 0 0 1616905731 1616905731 1616905731 1616905731 4096 0 0 b
16777221 91145643 0100644 1 568476 89939 0 0 1616905731 1616905731 1616905731 1616905731 4096 0 0 c d
# This works, because the shell expands * to three strings, and passes the three strings to the stat command.

> for f in *
> do
>   stat $f
> done
16777221 91145641 0100644 1 568476 89939 0 0 1616905731 1616905731 1616905731 1616905731 4096 0 0 a
16777221 91145642 0100644 1 568476 89939 0 0 1616905731 1616905731 1616905731 1616905731 4096 0 0 b
stat: c: stat: No such file or directory
stat: d: stat: No such file or directory
# This doesn't work, because the "*" in shell was expanded into three strings, but when the string "c d" was passed
# to stat, the shell parsed it as "stat c d", which means: stat the files c and d.

> for f in *
> do
>   stat "$f"
> done
16777221 91145641 0100644 1 568476 89939 0 0 1616905731 1616905731 1616905731 1616905731 4096 0 0 a
16777221 91145642 0100644 1 568476 89939 0 0 1616905731 1616905731 1616905731 1616905731 4096 0 0 b
16777221 91145643 0100644 1 568476 89939 0 0 1616905731 1616905731 1616905731 1616905731 4096 0 0 c d
# Great, now it works.

So you always have to remember to quote all strings that have been passed around, to preserve the spaces. But careful: everytime you use a string that is quoted, the quotes get stripped off. So you always add quotes back in. This gets particularly tedious when you pass strings that are file names to other shell invocations (for example running commands via ssh on other nodes). It's terrible time-consuming, hard to debug, and error prone.

For that reason, I actually think that file names should not be allowed to contain spaces (or other invisible or undisplayable characters), nor special characters like quotes of all types, $-signs, redirect characters like ">". Personally, I would not even allow two files to exist in the same directory whose only difference is the case (so file names should be case blind but case preserving). So if you create a file called "Elephant", it should always be returned as "Elephant", but it should be illegal to create files whose names are "elephant" or "elePhant". All that would prevent so many little annoying problems. But I know that Unix diehards disagree with my opinion.
 
Hi ralphbsz,

thank you very much for the examples and detailed explanation.

I have been reading upon that because I have received (useful) data, but with directory and filenames riddled with not UTF-8 characters, spaces and other characters, mixture of capital and lower case letters, etc. Because there are literally thousands or perhaps even hundred thousands of directories/files, it would be impossible to sort it out by hand.

So I started writing a script its main goal being to correct the above, but it is not as simple as some of the script snippets pretend. Cf. https://dwheeler.com/essays/filenames-in-shell.html.

So, I am really unsure how to approach it.

Kindest regards,

M
 
Hi mefizto,
I think that ralphbsz explained the problem well. My specific problem was, that designers were creating files, and we would have two files, one called 123.jpg and one called 123.jpg<space>. A week or so later, they needed to pull the file--they were using software designed for the fashion industry, which had records, and if their boss said, I need # 123.jpg, they would't know which style to pull and show their boss. Sometimes, (often, if I remember correctly), they would be duplicates. This was the only time I ran into this, and it was over 10 years ago, so I don't clearly remember the details. But the trouble is, for me, that if trying to track down a file, I wouldn't be able to distinguish between one with the space at the end and the one without the space.)
I also vaguely remember having a script to take created images, resize them, and put them somewhere, and those images with the space at the end would get missed.
 
Hi scottro,

thank you for the reply. Yes, ralphbsz did a great job; I originally addressed you and SirDice, because you had dealt with the problem, and I know that some of at least the directories have a space at the end, so I was hoping that yoou might remember how you detected it and remove it, as it does not seem to be as easy as my naive brain thought.
Kindest regards,
M
 
I think I put it in my post, I did something like cd into the directory and did ls * |cat -e. This puts a $ at the end of each file name so I would get things like
Code:
123.jpg$
123.jpg $
Then I was able to remove the offending files
 
One of the first things I learned was not to use spaces in a file name.

I use underscores or hyphens, letters and numbers all saved with UTF-8 encoding.
 
And I in addition avoid Non-Ascii. I never put consciously an hyphen at the beginning. If filenames
were restricted, I would not miss much.
All the saved styles I copy from USB stick to /local/share/fluxbox/styles/ as saved as US-ASCII.
I never use a space or hyphen to begin a file name though.
 
To answer the original question, expressions that begin with wildcards should start with ./, as in ./*tmp-3 or ./???. This even works in shells like zsh that support non-standard wildcards like **.

As for listing files containing non-graphical characters (e.g. ASCII blank/space and control characters like horizontal-tab and line-feed), env ls -q ./*[![:graph:]]* should work (env(1) is necessary to avoid shell aliases/functions). If you need to handle file names in a machine-parsable way, just use an expression containing wildcards like ./*.

Of course, if you disabled pathname expansion using set -f in your script, wildcards are unavailable anyway, and you'll need to find an alternative solution that works for you (e.g. temporarily enabling pathname expansion, saving the results of a wildcard expression to a bash array, and using that array as necessary).

Aside from the advice about not parsing ls(1) output, there are many other bits of advice about shell scripting that basically say "don't do this" or "it's best to do <X> this way when possible." For example, cd bin has two different behaviors, depending on whether CDPATH is set or unset:
  • CDPATH unset
    • ./bin exists - cd ./bin
    • else - "No such file or directory" error
  • CDPATH=$HOME:. (note: . must be explicitly included for the current working directory to be searched)
    • $HOME/bin exists - cd $HOME/bin
    • ./bin exists - cd ./bin
    • else - "No such file or directory" error
Executing cd ./bin limits the potential for accessing the incorrect directory, though you may want to use cd ./bin >/dev/null to avoid unnecessary output when CDPATH is set. devel/hs-ShellCheck is useful for detecting many possible issues, but I'm pretty certain this isn't one of the things it catches; I don't think there are a lot of scripts that get tripped up by CDPATH because it doesn't seem to be used much. Depending on what you script does, you probably can also just unset -v CDPATH as well. I guess that's yet another thing to include before you actually start writing a script :p

Welcome to shell—we don't have nasal demons, but you can still get burned 🔥
 
Does shell support real regular expressions?!
It's not a regular expression, it's a character class. Regular expressions can use character classes too, that's true. But a character class doesn't mean it's a regular expression.

Code:
     An asterisk (`*') matches any string of characters.  A question mark
     (`?') matches any single character.  A left bracket (`[') introduces a
     character class.  The end of the character class is indicated by a `]';
     if the `]' is missing then the `[' matches a `[' rather than introducing
     a character class.  A character class matches any of the characters
     between the square brackets.  A locale-dependent range of characters may
     be specified using a minus sign.  A named class of characters (see
     wctype(3)) may be specified by surrounding the name with `[:' and `:]'.
     For example, `[[:alpha:]]' is a shell pattern that matches a single
     letter.  The character class may be complemented by making an exclamation
     point (`!') the first character of the character class.  A caret (`^')
     has the same effect but is non-standard.
 
Personally I use all kinds of characters in file names, including spaces and UTF-8 characters. I really don’t see a reason to restrict myself in this regard. I mean, we’re not in the 80s anymore, and we’re not using MS-DOS anymore. FreeBSD has great support for unicode, wide characters and UTF-8. For example, a friend of mine has an “ü” in his name, so when I have a file name that contains his name, well, then I need UTF-8 for that. I’m certainly not going to cripple his name by restricting myself to US-ASCII like in the previous century. UTF-8 exists for 25 years, there is no excuse not to support it.

Regarding spaces in file names – I think this is just normal. Windows and Mac people use spaces in file names for ages. Why shouldn’t we? Is UNIX too dumb to handle it properly? No, BSD and Linux (and others) have zero problems with that. There sometimes is 3rd-party software that trips over it, but that’s clearly a bug in that software that needs to be fixed. In most programming languages, a file name is just a string, and it doesn’t care what kind of characters it contains. The only problem are macro languages and batch languages like the bourne shell, but when you take a course in shell programming, using proper quoting is one of the very first things that you’re taught. My own shell scripts are always space-save (they have to be, as I am not hesitant to use spaces in file names myself).

Having spaces at the end of file names might be a different matter. Personally I haven’t done that so far, just because I didn’t have a reason to, but I don’t think it should be forbidden. Someone might come up with a use for it. It’s not the UNIX philosophy to forbid things. As Doug Gwyn phrased it: “UNIX was not designed to stop you from doing stupid things, because that would also stop you from doing clever things.”

By the way, when handling file names with spaces in the shell, you don’t have to care about the quoting yourself most of the time. Modern shells (zsh, bash) automatically add quotes or escapes when necessary, when using the file name completion features (usually bound to the Tab key). For example (zsh):
Code:
$ touch foo "foo "
$ ls foo<Tab>
foo    foo\
Pressing the <Tab> key repeatedly cycles between the “foo” and “foo\ ” completions.
 
Back
Top