Replacing trailing space with single quote

Platform : RHEL 5.8

I want to end each line of this file with a single quote.

$ cat hello.txt
blueskies
minnie
mickey
gravity
snoopy

At VI editor's command mode, I have used the following command to replace the last character with a single quote.

~
~
~
:%s/$/'/g

Now, the lines in the file look like

$ cat hello.txt
blueskies '
minnie'
mickey '
gravity'
snoopy'

As you can see the line blueskies and mickey had a trailing space. So, the single quote was place after that.

Using vi (or any tool), how can I remove the trailing space and append a single quote at end of the line ?

Try:

:%s/[ ]*$/'/g
1 Like

Thank you very much Yoda.

What is the role of [ ] in your vi command ?

[] are metacharacter to match one item in the list.

[ ] matches a blank space. [ ]* means zero or more occurrences of blank space.

From Wikipedia: Regular Expression

A bracket expression. Matches a single character that is contained within the brackets. 
For example, [abc] matches "a", "b", or "c". [a-z] specifies a range which matches any lowercase letter from "a" to "z". 
These forms can be mixed: [abcx-z] matches "a", "b", "c", "x", "y", or "z", as does [a-cx-z].
The - character is treated as a literal character if it is the last or the first (after the ^) character within the brackets: [abc-], [-abc]. 
Note that backslash escapes are not allowed. The ] character can be included in a bracket expression if it is the first (after the ^) character: []abc].

Thank you again Yoda.

Would it be correct to say [ ]* means zero or more occurrences of blank space or any other character ?
If * wasn't there , then, only those lines which end with a trailing space will be replaced with a single quote. Right ?

Yes you are right..

That is not correct. It means zero or more occurrence of just blank space and not any other character.

If * is not there it will replace with single quote only those lines that have a trailing blank space.

1 Like

Got it yoda. Thanks again.

My above assumption was wrong as you have said. I have misunderstood the role of asterik * in regular expression.

In regular expression (unlike file pattern matching in shell) an asterik will match the preceding item (space in this case) zero or more times.
It is the asterik which did the trick of getting lines which didn't end with trailing space to be included (because of the 'zero times' property mentioned in the last sentence)

In the below mentioned file heroes.txt , the line batman has a trailing space

$ cat heroes.txt
jimihendrix
batman
katman
dogman
$

# The following returns only batman, because grep is looking for lines which end with man and at least one space.

$ grep "man[ ]$" heroes.txt
batman

# In the below attempt, both katman and dogman were also returned because the lines end with the pattern man followed by zero occurences of space

$
$ grep "man[ ]*$" heroes.txt
batman
katman
dogman

Hope my assumption is right this time.

Yes. Your assumption is correct John.

Just a minor note: There is no need to use [ ] since this is equivalent to a single space character. So both grep 'man[ ]*$' and grep 'man *$' match zero or more spaces after man

1 Like

Actually, in the code segment shown above there was no trailing space after batman (but I added one when I quoted your text above).

The command:

grep "man[ ]$" heroes.txt

doesn't look for

it looks for man followed by exactly one space at the end of the line. The asterisk you showed in your later example:

grep "man[ ]*$" heroes.txt

matches man followed by zero or more spaces at the end of the line. And, the commands:

grep "man[ ][ ]*$" heroes.txt
        and
grep "man  *$" heroes.txt
        and
grep -E "man +$"

(note two space characters after man in the second command) will all look for lines ending with man followed by one or more spaces at the end of the line.

Many systems have an egrep utility that is a synonym for grep with the -E option; some ancient systems may have egrep but not recognize -E as a valid option to grep.

Hope this helps.

1 Like