Sort input file by the results of a regex

regular expressionsorttext processing

I'd like to sort a file based on the results of a regex expression. For example, if I have the following property declarations in Obj-C

@property (nonatomic, strong) id <AlbumArtDelegate, UITextFieldDelegate> *albumArtView; // 1
@property (nonatomic, strong, readonly) UIImageView *profileView;  // 2
@property (nonatomic, strong, readwrite) UIButton *postFB;          // 3
@property (nonatomic, assign) UIButton *saveButton;      // 4

By default they will sort in order [4, 1, 2, 3], but I would like to sort them in order of the actual property names, [1, 3, 2, 4]. I can write a regular expression to tease out just the property name, is it possible for me to sort by the results of that expression?

Is there any built-in Unix tool that will do this for me? I'm working in Xcode, so VIM/emacs solutions won't help.

Also, the reason I'd like to do this using a regex is so that I can expand my sorting algorithm to work in other situations. Use it to sort method declarations, import statements, etc.

Best Answer

A general method to sort by an arbitrary function of the contents of the line is as follows:

  1. Get the key you want to sort by, and copy it to the beginning of the line
  2. Sort
  3. Delete the key from the beginning of the line

Here is a key you can use in this particular case: this sed program will output the the line from the last identifier to the end.

% sed -e 's/^.*[^[:alnum:]_]\([[:alpha:]][[:alnum:]_]*\)/\1/' < decls

albumArtView; // 1
profileView;  // 2
postFB;          // 3
saveButton;      // 4

To put these keys and the original lines side by side:

% paste <(sed -e 's/^.*[^[:alnum:]_]\([[:alpha:]][[:alnum:]_]*\)/\1/' < decls) decls

To sort them ...

| sort

and to leave just the second field (the original line)

| cut -f 2-

All together (sorting in reverse order, so there's something to show):

% paste <(sed -e 's/^.*[^[:alnum:]_]\([[:alpha:]][[:alnum:]_]*\)/\1/' < decls) decls \
  | sort -r \
  | cut -f 2-

@property (nonatomic, assign) UIButton *saveButton;      // 4
@property (nonatomic, strong, readonly) UIImageView *profileView;  // 2
@property (nonatomic, strong, readwrite) UIButton *postFB;          // 3
@property (nonatomic, strong) id <AlbumArtDelegate, UITextFieldDelegate> *albumArtView; // 1
Related Question