根据正则表达式的结果对输入文件进行排序

kub*_*ubi 8 text-processing sort regular-expression

我想根据正则表达式的结果对文件进行排序。例如,如果我在 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
Run Code Online (Sandbox Code Playgroud)

默认情况下,它们会按 [4, 1, 2, 3] 的顺序排序,但我想按实际属性名称 [1, 3, 2, 4] 的顺序对它们进行排序。我可以编写一个正则表达式来梳理出属性名称,我是否可以按该表达式的结果进行排序?

是否有任何内置的 Unix 工具可以为我执行此操作?我在 Xcode 中工作,所以 VIM/emacs 解决方案无济于事。

另外,我想使用正则表达式这样做的原因是我可以扩展我的排序算法以在其他情况下工作。使用它对方法声明、导入语句等进行排序。

ang*_*gus 13

按行内容的任意函数排序的一般方法如下:

  1. 获取要排序的key,复制到行首
  2. 种类
  3. 从行首删除键

这是您可以在这种特殊情况下使用的键:该sed程序将输出从最后一个标识符到结尾的行。

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

albumArtView; // 1
profileView;  // 2
postFB;          // 3
saveButton;      // 4
Run Code Online (Sandbox Code Playgroud)

将这些键和原始行并排放置:

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

对它们进行排序...

| sort
Run Code Online (Sandbox Code Playgroud)

并只留下第二个字段(原始行)

| cut -f 2-
Run Code Online (Sandbox Code Playgroud)

全部放在一起(以相反的顺序排序,所以有一些东西要显示):

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

?

@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
Run Code Online (Sandbox Code Playgroud)

  • @jw013:是的,我想他可能想使用其他工具来获取密钥——也许他知道 perl 或 awk。在这种情况下,使用 `paste` 是通用的“最小分母”解决方案。顺便说一句,那应该是 `\1` 和 `&amp;` 之间的制表符(无法与此处区分)。 (3认同)
  • 只是一个注释 b/c OP 可能想要适应这种方法。通过在 sed 替换命令的替换表达式中使用 `\1 &amp;`,您可以跳过 `decls` 临时文件和 `paste` 调用。此外,正则表达式需要调整为仅匹配标识符(如果行尾的注释包含任何没有数字的标识符,则给出的示例将失败)。 (2认同)