3
ffmj0010.09o:FFMJ                                                  MARKER NAME
ffmj0020.09o:BRMU                                                  MARKER NAME

In this text file (2 lines and no space between the lines) I need to extract 4 characters after ":" ("FFMJ", "BRMU") and save them in another text file. Which command do I need to use?

3

Using sed:

sed 's/.*:\(.\{4\}\).*/\1/' in > out
  • s: asserts to perform a substitution
  • /: stops the command / starts the pattern
  • .*:: matches any number of any character until the last : character and a : character
  • \(.\{4\}\): matches and groups 4 occurences of any character
  • .*: matches any number of any character
  • /: stops the pattern / starts the replacement string
  • \1: backreference replaced with the first captured group
  • /: stops the replacement string / starts the pattern flags

Sample output on the example file:

% cat in
ffmj0010.09o:FFMJ MARKER NAME
ffmj0020.09o:BRMU MARKER NAME
% sed 's/.*:\(.\{4\}\).*/\1/' in > out
% cat out
FFMJ
BRMU
3

Using awk and multiple delimiters

awk -F'[: ]' '{print $2}' in > out

Example

$ cat in
ffmj0010.09o:FFMJ                                                  MARKER NAME
ffmj0020.09o:BRMU                                                  MARKER NAME

$ awk -F'[: ]' '{print $2}' in 
FFMJ
BRMU
  • A much better awk answer than mine, forgot about multiple delimiters! – AJefferiss Oct 19 '15 at 14:23
3

If you are sure that you want exactly 4 characters before end of the line, you can do:

grep -Eo '.{4}$' file.txt >out.txt

Otherwise you can go for grep with PCRE to get all characters after : till the end of the line:

grep -Po '.*:\K[^:]+$' file.txt >out.txt

You can also use bash parameter expansion:

while IFS= read -r line; do echo "${line##*:}"; done <file.txt >out.txt

EDIT:

As @kos pointed out I might have misunderstood the question, if you want exactly 4 characters after : you can do:

grep -Po '.*:\K.{4}' file.txt >out.txt
1

Using grep:

cat oldFile | grep -o ":[A-Z]*" | grep -o "[A-Z]*" > newFile
cat oldFile |                                         # Read the file
               grep 
                    -o                                # Only give the greped data
                       ":[A-Z]*"                      # Find a : followed by 4
                                                      #  4 capital letters
                                 | grep -o "[A-Z]*"   # Remove the : from that

Then the > newFile outputs to a file.

On the example:

ffmj0010.09o:FFMJ MARKER NAME
ffmj0020.09o:BRMU MARKER NAME

goes to

FFMJ
BRMU
  • grep -o ":[A-Z]*" oldFile | grep -o "[A-Z]*" > newFile – A.B. Oct 19 '15 at 14:26
  • You could simplify this to a single command by adding the -P option and using a positive look-behind: grep -Po "(?<=:)[A-Z]*" oldFile > newFile – kos Oct 19 '15 at 14:34
  • @kos I don't understand how that works so I'll leave it at that. This is the method I go for to remove unwanted strings (or get wanted ones) but that is a useful trick. – Tim Oct 19 '15 at 14:35
  • @A.B. yeah, personal preference of mine is cat. – Tim Oct 19 '15 at 14:36
  • Basically It just means "if what preceeds what is following me (me=(?<=:)) is a : character, then don't discard this as a non-match, but don't match me". Also in this case just grep -Po ":\K[A-Z]*" oldFile > newFile (\K=clear what is matched until now) would do. It would save you one command :D – kos Oct 19 '15 at 14:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.