With sed
you can substitute by occurrence - so you just ask for the fifth <\t
ab>-delimited [1] field and for any numbers within it by ruling out other possible matches:
sed 's/[^\t0-9]*\([0-9]*\)[^\t]*/\1/5' <infile
After doing a copy to my clipboard of the other examples here I did:
xsel -bo | unexpand -a | sed ...
...to unexpand
-a
ll <tab>-sized space sequences into an actual <tab>. And it printed...
1 2 3 4 2458 6
a b c d 45
a1 b2 c3 d4 78 f6
...which just isolates the first integer in the 5th column. I'm not sure if that's what you want, though. If you just want the first integer from the fifth column on a line all its own, that's far easier (and much faster).
<infile \
cut -f5 | tr -cs '0-9\n' \\t |
expand -t1,2,4 | cut -d' ' -f-2
...which first cut
s the fifth <tab>-delimited [2] field of data per line in full (to avoid issues which may be caused by multiple integers per field) and then tr
anslates into a single <tab> every -s
queezed sequence of characters -c
omplementary to the set of \n
ewlines and 0-9
standard digits [3].
This means that in the output the first integer will be in either the first or second field - because the first field is now either empty (led by a <tab>) or your digit sequence depending on whether it was prefixed as you note. So I expand
the 1st and 2cd <tab>-stop positions on a line to a single space a piece, and the third to spaces - which effectively pads out a list of space-delimited fields into having either an empty first field or an empty third field. From there I can just cut
out the first two fields.
2458
45
78
...were my results for the example I used because they were all led by [cp]. and so all had leading <tab> s but those without would be staggered to the left. To additionally condense all results to a single line with each integer separated by a single space you can just append |xargs
to the command and get instead:
2458 45 78
Notes
Beware that the \t
escape is not a standard one where sed
is concerned - and in the context of a [bracket-expression]
character class it is arguably even explicitly contrary to the standard as the \
backslash and t
characters should each represent themselves there. I have used the escape here to more clearly demonstrate a readable intent - but you should probably use a literal <tab> in its place.
cut
delimits on <tab> characters by default, and so in this case the common -d [delim-char]
option is unnecessary - but also added this note to explain why.
As is noted in the link, the POSIX-standard requires that the [:digit:]
character class include the 0123456789 characters in all locales and in that sorting order and sorted ahead of any other inclusions in that class. Non C-locales may also include other localized numeral sets - which a GNU tr
probably will not handle appropriately as they are likely represented by multiple bytes - but only the standard numeral set is more likely the least surprising result in most cases anyway, and so using [:digit:]
unless you definitely want to match characters in both the standard Arabic numeral set and some other locale-dependent set of numerals is probably not advisable.
or
part of the text of the file, or are these 6 different examples of what the column might contain? It would help if you gave a few examples of full lines.sed -e 's/\([^[:digit:]]*\([[:digit:]]*\).*\)/\2;\1/'
, although I've probably missed some simpler way to write it)