3

I have a record like :

2011-05-29 17:51:34 => 'HS|CMGC|RN431|CI13950|CH7-4a37-afe2-acabfc9d262d|DA110529|TI175133|'

I want my final output to be something like:

2011-05-29 17:51:34  CI13950

I can get each part using cut like this:

$ cut -c 1-19
2011-05-29 17:51:34
$ cut -d  '|' -f 4
CI13950

I am unable combine the two as:

$ cut -c 1-19 -d  '|' -f 4
cut: only one type of list may be specified

Any suggestions?

3 Answers 3

4

Cut does its job once. You can run something through cut twice to pare it down even further, but it sounds like you need to use something like awk, sed, or perl instead.

Example of running multiple cuts:

cut -f 2 | cut -c 3-6

Example using perl that will work on your data line:

perl -pne "s/=> '([^|]+\|){3}([^|]+)/\2/g"

Here is a sed version from Fred in the comments:

sed -re "s/=> ([^|]*\|){3}([^|]*).*/\2/"
3
  • sorry mate , but your reply looks clipped out ..
    – Ricko M
    Commented Jun 2, 2011 at 9:48
  • 1
    Ya it got cut :) I accidentally hit save while I was still testing code in a terminal.
    – Caleb
    Commented Jun 2, 2011 at 9:50
  • 1
    The same thing using sed: sed -re "s/ => ([^|]*\|){3}([^|]*).*/ \2/"
    – Peter.O
    Commented Jun 2, 2011 at 12:49
4
awk '{split($NF,x,"|"); print $1, $2, x[4]}'
0

This question looks oddly familiar, although I see this actually came first.

The simplest, most readable approach I see is using Awk like so:

awk -F'|' '{print substr($0,1,19), $4}' text.txt

This is exactly equivalent to your attempted command cut -c 1-19 -d '|' -f 4, except that it's working code. ;)

You must log in to answer this question.

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