5

I have a log file which looks like:

Mar 23 08:20:23 New file got created in sec: 235
Mar 23 08:21:45 New file got created in sec: 127
Mar 23 08:22:34 New file got created in sec: 875
Mar 23 08:25:46 New file got created in sec: 322
Mar 23 08:26:12 New file got created in sec: 639

I need the output to look like:

Mar 23 08:20:23 : 235
Mar 23 08:21:45 : 127
Mar 23 08:22:34 : 875
Mar 23 08:25:46 : 322
Mar 23 08:26:12 : 639

What I am able to do is just grep either first part or the last part of the line. I am not able to put the two together. How can I get the desired output from my input?

  • @StephenRauch what if the middle content of the line is not same always? – IAmAndroid Mar 24 '17 at 4:02
  • @StephenRauch Yes the length is always the same. – IAmAndroid Mar 24 '17 at 4:13
  • I updated my answer based on knowing the length will be the same. – MikeD Mar 24 '17 at 4:37
9

you can do something like this

awk '{print $1,$2,$3,":",$NF}' logfile
  • 2
    It is better to use $NF instead of $10 to make it working as requested without dependency on the middle part. NF refers to the number of fields (10 in this case). – pabouk Mar 24 '17 at 9:46
  • @pabouk that would be best ! i have changed it as per your suggestion... – Prem Joshi Mar 24 '17 at 9:52
  • It's also possible to use $(NF - 1) to get the penultimate field, etc. – deltab Mar 24 '17 at 15:50
  • works exactly I wanted it to. – IAmAndroid Mar 25 '17 at 17:40
  • 1
    @IAmAndroid I'm glad ..... Keep scripting .... – Prem Joshi Mar 26 '17 at 5:16
10

You can use cut as:

Command:

cut --complement -c17-43 file1.txt

Output:

Mar 23 08:20:23 : 235
Mar 23 08:21:45 : 127
Mar 23 08:22:34 : 875
Mar 23 08:25:46 : 322
Mar 23 08:26:12 : 639
  • 1
    Note that this may fail when the day of the month is a single digit, depending on whether it is zero-padded. – David Conrad Mar 24 '17 at 12:01
4

You can use sed:

sed -r "s/^(.{15} ?).*(.{5})$/\1\2/" logfile

Per suggestions, I have made the first pattern accommodate single-digit days which may not be zero-padded, and use .* for the middle pattern to be more flexible.

  • what if the middle content of the line is not same always? – IAmAndroid Mar 24 '17 at 3:57
  • 1
    It is much better to use .* instead of .{27} and anchor to the start and end of the line using ^ and $ (but it should work without the anchors too) otherwise you are uselessly depending on the length of the middle part. – pabouk Mar 24 '17 at 9:49
  • This will fail if single-digit days aren't zero-padded. – David Conrad Mar 24 '17 at 12:01
  • Thanks all, I have updated the patterns to accommodate your suggestions and concerns. – MikeD Mar 24 '17 at 23:29
3

In awk, it's something like this. Very simple.

[zee@dev-instance temp]$ cat file1.txt 
Mar 23 08:20:23 New file got created in sec: 235
Mar 23 08:21:45 New file got created in sec: 127
Mar 23 08:22:34 New file got created in sec: 875
Mar 23 08:25:46 New file got created in sec: 322
Mar 23 08:26:12 New file got created in sec: 639
[zee@dev-instance temp]$ awk -F" " '{ print $1" "$2" "$3" : "$10 }'<file1.txt 
Mar 23 08:20:23 : 235
Mar 23 08:21:45 : 127
Mar 23 08:22:34 : 875
Mar 23 08:25:46 : 322
Mar 23 08:26:12 : 639
[zee@dev-instance temp]$ 
2

How about this:

sed -e 's/^\(.\{4\}\).*\(.\{4\}\)$/\1 \2/'

(You can figure out the I/O redirection or give filename, etc. See sed(1) for more invocation info.)

Here, I have chosen the number of characters to be exactly 4, but you could substitute any number(s) you like. Note that the first and last number of characters can even be different:

sed -e 's/^\(.\{5\}\).*\(.\{2\}\)$/\1 \2/'

This would return the first 5 characters and last 2 characters of each line. I'll leave it to you to figure out how to parameterize this further.

Also, note that I have chosen sed(1) rather than grep(1) (or one of its variants). I know that this may not be quite what you want as you did ask for a grep regex, not a sed regex.

2
perl -F '' -lane 'print @F[0..15, -5..-1]' yourfile

Explanation

-F '' => split the line into individual characters, IOW, all fields are 1-char thick.

-l => ORS=\n

-a => @F array holds the fields, e.g., $F[15] => holds the 16-th character

-n => don't print unless specifically asked to

@F[0..15, -5..-1] => is a slice of the array @F with the first 16 characters, and the last 5 characters, something along the lines of cut

  • Err, the question only shows 10 columns, so what would $F[15] be selecting? – thrig Mar 24 '17 at 13:48
  • I guess some explanation would be welcomed. OP might want to adapt command to fit other need, of file format change. – Archemar Mar 24 '17 at 14:00
  • You need to realize that the columns are all 1-character wide, due to the -F option being supplied with nothing. Better to say: -F '' I guess to make the intent unambiguous. – user218374 Mar 24 '17 at 14:09
1

you can do something like this

cut -c1-15 logfile > file;

cut -c44- logfile > file1;

paste file file1 > logfilenew;

rm file file1;

cat logfilenew

output will store in the logfilenew.

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.