This will solve your 1st issue:
echo "[STATUS REPORT] PROJECT" | awk '{ gsub(/PROJECT/, "A\\&A"); print }'
(&
is a special char in awk substitution: it means "what has been matched". You need to escape if with a \
. And as you are in a awk string, your need to put 2 \
to produce one as \
escape the next char as in \n
.)
This will solve your 2nd issue:
ProjectName=toto
echo "[STATUS REPORT] PROJECT" | awk -v "ProjectName=$ProjectName" '{ gsub(/PROJECT/, ProjectName); print }'
(Edit: notice the newly added "
around ProjectName=$ProjectName
so a space in ProjectName
does not break the script.)
But awk is a big tool to perform string substitution, you might want to use sed:
echo "[STATUS REPORT] PROJECT" | sed -e 's/PROJECT/A\&A/'
ProjectName=toto;
echo "[STATUS REPORT] PROJECT" | sed -e "s/PROJECT/${ProjectName//\//\\/}/"
(Edit: a /
in ProjectName
will was breaking the initial solution. I added the escaping of slashes, but some other char(s) still breaks it: &
, \1
, ... I think plain bash shell bellow is safer.)
or in plain bash shell:
msg="[STATUS REPORT] PROJECT"
echo ${msg//PROJECT/A&A}
ProjectName=toto
echo ${msg//PROJECT/$ProjectName}
Summary:
- Windows: anything except ASCII's control characters and
\/:*?"<>|
- Linux, OS-X: anything except null or
/
On all platforms it is best to avoid non-printable characters such as the ASCII control-characters.
Windows
In Windows, Windows Explorer does not allow control-characters or \/:*?"<>|
You can use spaces. If you use spaces, you will often have to quote the filename when used from the command line (but GUI apps are unaffected so far as I know). Windows filesystem such as NTFS apparently store the encoding with the filename, but UTF-16 is standard.
Some parts of Windows are case-sensitive, other parts are case-insensitive.
It is easy to create distinct filenames like "Ab" and "ab" on a Windows NTFS filesystem. These names refer to separate files which contain distinct separate content. However, although the Windows command-prompt will happily list both files using dir
, you cannot easily access or manipulate one of them using commands such as type
. See below.
Linux, OS-X
In Linux and OS-X only /
of the printable ASCII set is prohibited I believe. Some characters (shell metacharacters like *?!
) will cause problems in command lines and will require the filename to be appropriately quoted or escaped.
Linux filesystems such as ext2, ext3 are character-set agnostic (I think they just treat it more or less as a byte stream - only nulls and /
are prohibited). This means you can store filenames in UTF-8 encoding. I believe it is up to the shell or other application to know what encoding to use to properly convert the filename for display or processing.
Conclusion
So you could probably safely use something like ✣
(if it weren't so hard to type)
Case-(in)sensitivity in Windows
C> dir /B
Ab
aB
аB
C> type Ab
b
b
C> type aB
b
b
C> type аB
unicode homograph
Note that we cannot type the contents of the second file, the Windows type
command just returns the contents of Ab instead. The third file would be distinct from aB on Linux also.
(Windows 10 NTFS).
Best Answer
You can create an Automator service to do this in all applications that support services (which is almost all of them).
Open Automator and select to create a Service that receives selected text in any application and check Output replaces selected text.
Add a single Run Shell Script action from the library, and paste the following script code:
This specific script, a simple
sed
substitution will remove all non alpha-numeric characters from the file name. It usesa-zA-Z0-9
as a whitelist of allowed characters, add to it as desired.You can do other actions as well, and chain them together. For example,
tr [A-Z] [a-z]
will lowercase everything, andsed 's|[^a-zA-Z0-9]||g' | tr [A-Z] [a-z]
will combine the two.Save as e.g. Sanitize Filename, and optionally assign a keyboard shortcut in System Preferences » Keyboard » Keyboard Shortcuts » Services. You should be able to invoke services using Quicksilver as well, just type their name.
Whenever you're in a Save as… or similar dialog, select the suggested file name (it's selected by default):
Invoke the service Program Menu » Services » Sanitize Filename (or use the keyboard shortcut you invoked). It will pipe the file name through the script, and use its output to replace the selection.
For title-casing and removing bad characters (I also keep underscore, dot and hyphen in), the following script code seems to mostly work for me: