4

I have the following type of output from a find and grep pipe

./Columbia/815425_0001104659-11-049107.txt:         CENTRAL INDEX KEY:              0000815425
./Columbia/815425_0001104659-12-060231.txt:         CENTRAL INDEX KEY:              0000815425
./Columbia/815425_0001104659-13-066298.txt:         CENTRAL INDEX KEY:              0000815425
./Dimensional Advisors/355437_0001137439-04-000108.txt:         CENTRAL INDEX KEY:              0000355437
./Dimensional Advisors/355437_0001137439-05-000205.txt:         CENTRAL INDEX KEY:              0000355437
./Dimensional Advisors/355437_0001137439-06-000306.txt:         CENTRAL INDEX KEY:              0000355437
./Dimensional Advisors/355437_0001137439-08-000364.txt:         CENTRAL INDEX KEY:              0000355437
./Dimensional Advisors/355437_0001137439-09-000076.txt:         CENTRAL INDEX KEY:              0000355437
./Dimensional Advisors/355437_0001137439-12-000295.txt:         CENTRAL INDEX KEY:              0000355437
./Dimensional Advisors/355437_0001140361-10-035592.txt:         CENTRAL INDEX KEY:              0000355437

I would like to obtain

Columbia 0000815425
Columbia 0000815425
Columbia 0000815425
Dimensional Advisors 0000355437
Dimensional Advisors 0000355437
Dimensional Advisors 0000355437
Dimensional Advisors 0000355437
Dimensional Advisors 0000355437
Dimensional Advisors 0000355437
Dimensional Advisors 0000355437

I was thinking sed and grep, but I am stuck with how to combine everything: matching the first part: (how do I match just before the /?)

erik Funds$ cat myoutput | egrep -o "[A-Z].*/"
Columbia/
Columbia/
Columbia/
Dimensional Advisors/
Dimensional Advisors/
Dimensional Advisors/
Dimensional Advisors/
Dimensional Advisors/
Dimensional Advisors/
Dimensional Advisors/

and the last 10 digit numbers:

erik Funds$ cat myoutput | egrep -o "[0-9]{10}$"
0000815425
0000815425
0000815425
0000355437
0000355437
0000355437
0000355437
0000355437
0000355437
0000355437
  • 2
    how do I match just before the /? ... use perl regex with lookahead.. grep -oP "[A-Z].*(?=/)" – Sundeep Aug 30 '16 at 11:17
  • too bad cut -f can't index from the end of the list – loa_in_ Aug 30 '16 at 22:27
7

awk with / as field separator, and then printing field 2 and field 3 (with necessary zero padding):

... | awk -F/ '{ printf("%s %010d\n", $2, $3) }'

Example:

$ cat file.txt 
./Columbia/815425_0001104659-11-049107.txt:         CENTRAL INDEX KEY:              0000815425
./Columbia/815425_0001104659-12-060231.txt:         CENTRAL INDEX KEY:              0000815425
./Columbia/815425_0001104659-13-066298.txt:         CENTRAL INDEX KEY:              0000815425
./Dimensional Advisors/355437_0001137439-04-000108.txt:         CENTRAL INDEX KEY:              0000355437
./Dimensional Advisors/355437_0001137439-05-000205.txt:         CENTRAL INDEX KEY:              0000355437
./Dimensional Advisors/355437_0001137439-06-000306.txt:         CENTRAL INDEX KEY:              0000355437
./Dimensional Advisors/355437_0001137439-08-000364.txt:         CENTRAL INDEX KEY:              0000355437
./Dimensional Advisors/355437_0001137439-09-000076.txt:         CENTRAL INDEX KEY:              0000355437
./Dimensional Advisors/355437_0001137439-12-000295.txt:         CENTRAL INDEX KEY:              0000355437
./Dimensional Advisors/355437_0001140361-10-035592.txt:         CENTRAL INDEX KEY:              0000355437

$ awk -F/ '{ printf("%s %010d\n", $2, $3) }' file.txt
Columbia 0000815425
Columbia 0000815425
Columbia 0000815425
Dimensional Advisors 0000355437
Dimensional Advisors 0000355437
Dimensional Advisors 0000355437
Dimensional Advisors 0000355437
Dimensional Advisors 0000355437
Dimensional Advisors 0000355437
Dimensional Advisors 0000355437
4
$ sed -E 's|^\./([^/]+)/.*\s([0-9]+)$|\1 \2|' myoutput
Columbia 0000815425
Columbia 0000815425
Columbia 0000815425
Dimensional Advisors 0000355437
Dimensional Advisors 0000355437
Dimensional Advisors 0000355437
Dimensional Advisors 0000355437
Dimensional Advisors 0000355437
Dimensional Advisors 0000355437
Dimensional Advisors 0000355437
  • -E extended regular expression
  • ^\./ match ./ at beginning of line
  • ([^/]+) capture non / characters
  • /.*\s match / and any number of characters followed by white-space character
  • ([0-9]+)$ capture digits at end of line
  • \1 \2 paste the captured groups with space in between

sed allows to use any delimiter except \ and newline, so using | here to avoid escaping /

2

awk - using FS splitting

If you set awk to split the input on slash delimiters, and then resplit on space delimiters, you can pick out the correct fields:

<infile awk '{ n=$2; FS=" +"; $0=$0; print n, $NF; FS="/" }' FS=/

GNU awk - using FPAT field description

If you describe the fields correctly to with FPAT you can get the desired results. Here is an example that works with your input:

<infile awk '{ print $1, $NF }' FPAT='[[:alnum:][:space:]]+'

Output

Columbia               0000815425
Columbia               0000815425
Columbia               0000815425
Dimensional Advisors               0000355437
Dimensional Advisors               0000355437
Dimensional Advisors               0000355437
Dimensional Advisors               0000355437
Dimensional Advisors               0000355437
Dimensional Advisors               0000355437
Dimensional Advisors               0000355437
  • Not the output OP wants i'm afraid.. – heemayl Aug 30 '16 at 13:08
  • @heemayl: My mistake. The updated version produces the correct result, although is not as simple ... – Thor Aug 30 '16 at 13:40
  • Equivalent but less fiddly: awk '{split($1,a,"/"); print a[2],$NF}' – dave_thompson_085 Sep 3 '16 at 10:20
  • @dave_thompson_085: using $1 will not capture multi-word arguments. – Thor Sep 4 '16 at 19:28
  • Argh, you're right. sorry. – dave_thompson_085 Sep 8 '16 at 4:21
2

Here is an alternative solution, piping your data through tr and cut :

…|tr ':' '/'|cut -d'/' -f2,5|tr -d '/'

The first tr replaces : with /, so that cut can use / as a delimiter to isolate the last column, as it already does for the second one. Since you extract several columns, cut's output will contain a / as a separator, unless you use its --output-delimiter, but it's shorter to simply delete this character using tr -d.

If you don't want the multiple spaces you can add a pipe through sed :

…|sed 's/  */ /g'

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.