The escape character (\) can be used to escape end of line, for example.,
echo This could be \
a very \
long line\!
Output:
This could be a very long line!
However, isn't end of line (new line) represented by \n which has two characters? Shouldn't the result of the escape be the literal of \n? For example,
echo $'\\n'
Output:
\n
I am not trying to echo a new line. I am wondering why \ is able to new line character (\n) which has two character instead of just escape the backslash in the new line character and produce the literal of \n.
Actually, \n is not really a newline character—it is an escape sequence that represents a newline (which is just one character in Linux). The \ at the end of a line escapes the actual newline character that you type in using the enter key. You can look at what ASCII values represent different characters using hexdump:
%echo $'\\n'
\n
%echo $'\\n' | hexdump -C
00000000 5c 6e 0a |\n.|
00000003
You will notice that echo printed out 3 characters: \ (5c), n (6e), and a newline (0a). You will also notice that on the right hand side of the hexdump output, newline shows up as a ".", because it is considered a non-printing character.
Newline is the name given in the UNIX world to a character that ends a line in a line-oriented file (or in a terminal). In the UNIX/Linux world this corresponds to the ASCII linefeed character.
Different systems use different conventions to end lines: Windows uses a sequence of carriage return and line feed, while Mac originally used a single carriage return. This confusion stems from the fact that these were originally commands needed to move a printer's print head to the beginning of a new line.
\n is a conventional way of expressing the end of line character in code, again originally in the UNIX world, more precisely in the C language. Note that when reading a text file C reads a single newline character even on systems where this is really a two character sequence.
Related
The following description is found in the line break (\n) section of the pattern and search commands in the official vim documentation.
http://vimdoc.sourceforge.net/htmldoc/pattern.html#pattern-atoms
\n matches an end-of-line */\n*
When matching in a string instead of buffer text a literal newline
character is matched.
I don't understand
When matching in a string instead of buffer text a literal newline character is matched.
When can this be detected?
I have done the following experiment. I put the following in a file and typed /\n on the vim command line, but it did not match a literal newline character in all cases.
"\n"
'\n'
\n
By 'string' it doesn't mean text in the buffer that's surrounded by quotes, but rather the {string} argument that you would pass to the 'substitute' function. See :help substitute()
I want to replace a line, that represents a part of mathematical equation:
f(x,z,time,temp)=-(2.0)/(exp(128*((x-2.5*time)*(x-2.5*time)+(z-0.2)*(z-0.2))))+(
with a new one similar to the above. Both new and old lines are saved in bash variables.
Main problem is that mathematical equation is full with special characters that do not allow proper search and replace in bash mode, even when I used as delimiter special character that is not used in equation.
I used
sed -n "s|$OLD|$NEW|g" restart.k
and
sed -i "s|$OLD|$NEW|g" restart.k
but all times I get wrong results.
Any idea to solve this?
There is only * in your pattern here that is special for sed, so escape it and do replacement as usual:
sed "s:$(sed 's:[*]:\\&:g' <<<"$old"):$new:" infile
if there are more special characters in your real sample, then you will need to add them inside bracket []; there are some exceptions like:
if ^ character: it can be place anywhere in [] but not first character, because ^ character at first negates the characters within its bracket expression.
if ] character: it should be the first character, because this character is also used to end the bracket expression.
if - character: it should be the first or last character, because this character is also can be used for defining the range of characters too.
There seems to be some sort of asymmetry in the way Vim treats ^M when doing string replacement (:s/x/y/).
Perhaps an example is best; say we have this text file:
foo:bar:biz
I want to split this into lines. This works fine:
:s/:/^M/g
(note that ^M is produced by typing Ctrl-V, Enter)
This results in the text file:
foo
bar
baz
Now, if I undo that and try again, I notice that this does not work:
:s/:/\n/g
Here, the resulting text is:
foo^#bar^#biz
That is to say, they are joined by the ASCII NUL byte (0x00).
Question 1: Why does using \n in the replacement result in NUL bytes?
Now, I figure "okay, I guess ^M is used as the 'line separator' character in some way, for Vim; I can work with that".
So I do another experiment, starting with the one-item-per-line text file:
foo
bar
baz
and now, I want to join them with colons, so it looks like the very first incarnation, above.
So I run:
:%s/^M/:/
But this fails, with the error:
E486: Pattern not found: ^M
However, this command does work:
:%s/\n/:/
producing:
foo:bar:biz:
(I can get rid of the trailing colon myself)
So Question 2: Why does \n work in this case, where ^M does not?
And ultimately, Question 3: Why is there this asymmetry between \n and ^M depending on whether it's on the right- or left-hand side of a string replacement command?
When searching, \n is a "catch-all" atom that conveniently matches any kind of "end-of-line": CRLF, CR, and LF.
When replacing, \n is <Nul> and represented as ^#.
When replacing, \r is the legal "end-of-line" for the current fileformat.
In short, get used to this pattern and carry on:
:s/\n/\r
See :help NL-used-for-Nul and CR-used-for-NL.
I have searched for the list of metacharacters in Bash but space is not enlisted.
I wonder if I'm right by assuming that space is the "token separation character" in Bash, since it not only works as such with Shell programs or builtins but also when creating an array through compound assignment - quotes escape spaces, just like they do most other metacharacters.
They cannot be escaped by backslashes, though.
Parameters are passed to programs and functions separated by spaces, for example.
Can someone explain how (and when) bash interprets spaces? Thanks!
I've written an example:
$ a=(zero one two)
$ echo ${a[0]}
$ zero
$ a=("zero one two")
$ echo ${a[0]}
$ zero one two
From the man page:
metacharacter
A character that, when unquoted, separates words. One of the following:
| & ; ( ) < > space tab
^^^^^
According to the Posix shell specification for Token Recognition, any shell (which pretends to be Posix-compliant) should interpret whitespace as separating tokens:
If the current character is an unquoted <newline>, the current token shall be delimited.
If the current character is an unquoted <blank>, any token containing the previous character is delimited and the current character shall be discarded.
Here <blank> refers to the character class blank as defined by LC_CTYPE at the time the shell starts. In almost all cases, that character class consists precisely of the space and tab characters.
It's important to distinguish between the shell mechanism for recognizing tokens, and the use of $IFS to perform word-splitting. Word splitting is performed (in most contexts) after brace, tilde, parameter and variable, arithmetic and command expansions. Consider, for example:
$ # Setting IFS does not affect token recognition
$ bash -c 'IFS=:; arr=(foo:bar); echo "${arr[0]}"'
foo:bar
$ # But it does affect word splitting after variable expansion
$ bash -c 'IFS=: foobar=foo:bar; arr=($foobar); echo "${arr[0]}"'
foo
Yes it is. From the Bash Reference Manual's Definitions section:
blank
A space or tab character.
…
metacharacter
A character that, when unquoted, separates words. A metacharacter is a blank or one of the following characters: ‘|’, ‘&’, ‘;’, ‘(’, ‘)’, ‘<’, or ‘>’.
Unfortunately, I can't post any pictures due to my lack of reputation but it looks like "^#".
For some context, I have a script that goes through a list of names to generate a configuration file. I run an executable with those configuration and if it doesn't run, the script will proceed to the next name and erase the content of the previous configuration. However, if the executable does run, the script will move on to the next name and append onto the exist configuration. The problem is that when the first iteration is erased, it leaves behind a symbol that would conflict with all subsequent iterations. Any idea what this symbol mean? Much appreciated.
It doesn't just look like "^#", it is "^#". The ^ denotes a control character; for example ^X is Control-X. The null character can be entered on most keyboards by typing Control-#.
Look at a table of ASCII codes. The Control key, in many cases, modifies a character by subtracting 64 from its ASCII value; thus Control-G is character (71 - 64) or 7, the ASCII BEL character.
As special cases, the ASCII DEL character, 127, is represented as "^?", and the NUL character can be entered (on most keyboards) by typing Control-Space. (Vim doesn't use "^ " to represent the NUL character because it would be difficult to read.)
It's how vim displays ASCII nul, i.e. a zero byte.
A simple way to find out the numeric value of a character is to pipe the file through a hex tool such as xxd and you will see the ^# character has value 00
You can create an empty file then (in input mode) type Ctrl-V Ctrl-Shift-# to enter the ^# character, then filter it with :%!xxd and you will get:
0000000: 000a ..
This shows there are two characters with values 00 and 0a (which is a newline)