12

I have a file with pipe-separated fields. I want to print a subset of field 1 and all of field 2:

cat tmpfile.txt

# 10 chars.|variable length num|text
ABCDEFGHIJ|99|U|HOMEWORK
JIDVESDFXW|8|C|CHORES
DDFEXFEWEW|73|B|AFTER-HOURS

I'd like the output to look like this:

# 6 chars.|variable length num
ABCDEF|99
JIDVES|8
DDFEXF|73

I know how to get fields 1 & 2:

cat tmpfile.txt | awk '{FS="|"} {print $1"|"$2}'

And know how to get the first 6 characters of field 1:

cat tmpfile.txt | cut -c 1-6

I know this is fairly simple, but I can't figure out is how to combine the awk and cut commands.

Any suggestions would be greatly appreciated.

Grace Mahoney
  • 485
  • 1
  • 7
  • 14
user3486154
  • 121
  • 1
  • 1
  • 3

4 Answers4

14

You could use awk. Use the substr() function to trim the first field:

awk -F'|' '{print substr($1,1,6),$2}' OFS='|' inputfile

For your input, it'd produce:

ABCDEF|99
JIDVES|8
DDFEXF|73

Using sed, you could say:

sed -r 's/^(.{6})[^|]*([|][^|]*).*/\1\2/' inputfile

to produce the same output.

devnull
  • 118,548
  • 33
  • 236
  • 227
3

You could use cut and paste, but then you have to read the file twice, which is a big deal if the file is very large:

paste -d '|' <(cut -c 1-6 tmpfile.txt ) <(cut -d '|' -f2 tmpfile.txt )
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
2

Just for another variation: awk -F\| -vOFS=\| '{print $1,$2}' t.in | cut -c 1-6,11-

Also, as tripleee points out, two cuts can do this too: cut -c 1-6,11- t.in | cut -d\| -f 1,2

Etan Reisner
  • 77,877
  • 8
  • 106
  • 148
  • Or if you can guesstimate the maximal length of the second field, use two cuts; `cut -c1-6,11-16 t.in | cut -d'|' -f1-2` – tripleee Apr 01 '14 at 18:15
1

I like a combination of cut and sed, but that's just a preference:

cut -f1-2 -d"|" tmpfile.txt|sed 's/\([A-Z]\{6\}\)[A-Z]\{4\}/\1/g'

Result:

# 10-digits|variable length num
ABCDEF|99
JIDVES|8
DDFEXF|73

Edit: (Removed the useless cat) Thanks!

rpf
  • 49
  • 3