I have a file containing lines in below e.g. format -

[[email protected], [email protected]], Payment processed - 23499, params = {'invoice':3243}

I only want the account numbers i.e. 23499. It's a number. Let's say it <account>. Its not a constant.

For that, I am trying to -

  1. Remove params ...
  2. Replace [...], from start of each line by whitespace

By ... I mean any string. I have tried -

# 1
# 2

All the things I have tried in # 2 have not worked. What am I doing wrong? How do I get <account>? Help me out.

  • 1
    It seems that there has been serious confusion for what you actually want the output to be. Given the example input you mention, what would your desired output look like?
    – HalosGhost
    Sep 25, 2014 at 17:00
  • Coul it be that there is a comma missing in "2."? I had read "from start of each line by whitespace" as something with a whitespace separator. But with a comma, it's pretty clear: "Replace [...], from start of each line, by whitespace." Sep 25, 2014 at 17:03
  • 23499. 23500. 36754. 43266 and so on. Account numbers from email subject Sep 25, 2014 at 17:04
  • And no whitespace in front of them? Sep 25, 2014 at 17:52
  • Each number on newline. I couldn't type a newline in the comment :( Sep 25, 2014 at 18:16

4 Answers 4


You can use following sequence to only retain the account numbers (cudo's to J.D.Mohr)
note the space after the r in the command

:%norm $F,d$Bhv0r 

This assumes that there's only one , after the number you want to retain


:     -> Enter command mode
%norm -> Applies a normal command to the entire file
$     -> Jump to end of line
F,    -> Find preceding ,
d$    -> Delete until end of line
B     -> Jump back a word
hv0   -> Go left one character and select until beginning of line
r     -> replace selected text with <space>
  • 1
    @HalosGhost - The idea is to type the entire sequence on the line and hit return. Sep 25, 2014 at 16:17
  • This is close, but doesn't quite do what was asked for. They wanted whitespace in place of the junk at the beginning of the line. :%norm $F,d$Bhv0r works for me (with an impotant space at the end there).
    – talkloud
    Sep 25, 2014 at 16:17
  • @J.D.Mohr - I missed that, tx for the correction. Sep 25, 2014 at 16:19
  • Yes i am able to remove [emails]. But the solution seems little difficult. Whats wrong with the things i have tried in #2? Sep 25, 2014 at 16:49
  • @HussainTamboli - You are not searching for anything in your first two regexes and the last two are greedy. Try /\v^.{-}\d+ as regex and work from there. The {-}is not greedy as opposed to *. The ^ is to start from the beginning of the line and the \d+ is a number followed by other numbers. Sep 25, 2014 at 17:49

To get only the <account> string

awk '{print $6}' file| sed 's/,//' >> newfile

For possible future usage of the main data, this could be useful

  • 1
    I imagine this could be done with awk alone. It certainly doesn't need the pipe from cat, at least.
    – HalosGhost
    Sep 25, 2014 at 15:33
  • @HalosGhost You're correct
    – tachomi
    Sep 25, 2014 at 15:35
  • I would prefer if i get the solution in vim Sep 25, 2014 at 16:46

If you would look for <account> (something like <12345>) and have have < and > only in <account>, as it looked like in the original version of the question, then this could work:


It matches < and > with anything between - which is in a group, and anything before and after in the line. That is replaced by just the group.

Answering the updated question:

If you do not have <account>, but a number in this place, with no < and >: this works in a similar way:

%s/\v.* - ([0-9]*), params =.*/\1/

It matches numbers, in a group to keep them. And it matches anything before that ends with " - ", and anything after that starts with , params =, both up to start or end of line.
So the expression matches the whole line, and is replaced by the matched group that contains the number.

It's using \v for "very magic" regular expressions see :help /magic.

  • Hi, I am really sorry I created a confusion. I don't have < and >. In fact <account> is a number. Sep 25, 2014 at 15:22
  • 1
    Oh, you should edit the question! Sep 25, 2014 at 15:22
  • But , params = is actually , params = , and ` - ` is ` - `? Sep 25, 2014 at 15:24
  • If I am able to remove emails it will be great (emails are put in []). I will easily be able to get the account numbers. Sep 25, 2014 at 16:11
  • The update in the second part of my answer should already output the number only. Sep 25, 2014 at 16:12

As easy as it might be to want to use vim (or sed for this), awk is actually entirely capable of doing this type of matching and substitution all on its own:

$ awk '{ sub(/^.* - /, ""); sub(/,.*$/, ""); print $0 }' file

The above matches everything (with awk's built-in sub() function) from the beginning of the line to the hyphen and space before the account number and replaces it with the empty string "". Then, it matches everything from the comma to the end of the line and replaces it with the empty string. This should robustly (e.g., regardless of how many emails or what their formatting might be) remove everything but the account number.

If you have access to gawk, then you can use a simpler solution (only one function call needed):

$ gawk 'match($0, /^.* - ([0-9]+),.*$/, a) { print a[1] }' file

Of course, the above solutions print the new data to stdout. If you wanted to save the new data for use later, all you would need to do is add > newfile to the end of the above command (note, that > overwrites; if you would prefer appending, you can use >>).

awk has many limitations of its own (for example, working with many files at the same time), so it's not always the best tool for this type of manipulation. However, it is quite good at what it does, so when your use-case lines up with its round-house, I'd strongly recommend using it.

In addition, the above solution requires no interactive interface (like vim) and no piping.

  • How can I replace emails by whitespace? Emails are put in [] Sep 25, 2014 at 16:08
  • you see I can easily remove some part from the lines using Visual mode. vim is just a preference. Sep 25, 2014 at 16:21
  • Ahh, I think I misread your question; you were wanting the all the leadup information to be padded with spaces, rather than completely removed? Do you want it padded with spaces equal to character count? Do you want the [] to remain?
    – HalosGhost
    Sep 25, 2014 at 16:22
  • No i want to remove emails and the [] brackets that contain those emails Sep 25, 2014 at 16:41
  • I added another solution that uses two sub() calls; the first matches everything up to the closing ] and the comma and space that follows and replaces it with the empty string. The second removes everything after the account field.
    – HalosGhost
    Sep 25, 2014 at 16:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .