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

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?


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

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. ;)

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.