bash:对文件的各个部分进行排序

时间:2016-12-15 09:40:26

标签: bash awk sed

我有一些"那种SQL"我希望对其进行部分排序的文件 - 以便以后能够相互比较。

CREATE TABLE BBBBBB
(
   ID bigint NOT NULL
   NAME varchar(50)
   CURRENCY varchar(3)
   SYS_START timestamp NOT NULL
   SYS_END timestamp NOT NULL
   TS_ID timestamp NOT NULL
   EXPORT int
)

CREATE TABLE AA
(
   ID bigint NOT NULL
   SYS_START timestamp NOT NULL
   SYS_END timestamp NOT NULL
   TS_ID timestamp NOT NULL
   NAME varchar(100) NOT NULL
)

我只想将括号内的部分排序。输出应为:

CREATE TABLE BBBBBB
(
   CURRENCY varchar(3)
   EXPORT int
   ID bigint NOT NULL
   NAME varchar(50)
   SYS_END timestamp NOT NULL
   SYS_START timestamp NOT NULL
   TS_ID timestamp NOT NULL
)

CREATE TABLE AA
(
   ID bigint NOT NULL
   NAME varchar(100) NOT NULL
   SYS_END timestamp NOT NULL
   SYS_START timestamp NOT NULL
   TS_ID timestamp NOT NULL
)

我试着将括号中的部分放入sed保持缓冲区并对它们进行排序,但我没有达到目标......我现在还没有其他想法。

4 个答案:

答案 0 :(得分:1)

gawk

gawk 'BEGIN{PROCINFO["sorted_in"] = "@ind_str_asc"}
      /^\(/{f=1}
      /^\)/{f=0
            for (i in a)
              print a[i]
            delete a}
      f{a[$1]=$0}
      !f' yourfile

检查 ideone 演示 here

来自docs

  

“@ ind_str_asc”按索引按升序排序,比较为   串;这是最基本的一种。 (在内部,数组索引是   总是字符串,所以'a [2 * 5] = 1'索引是“10”而不是   数字10。)

答案 1 :(得分:1)

使用awk

awk 'i {a[l++]=$0}
     /^\(/ {print; i=1}
     /^\)/ {n=asort(a); for(k=1; k<=n; k++){print a[k]} i=0; delete a; next}
     !i' File

答案 2 :(得分:1)

使用Vim的解决方案:

vim -c ":/^(/+1,/^)/sort | /^(/-1 | /^(/+1,/^)/sort | wq" x.txt

答案 3 :(得分:0)

Perl救援!

perl -ne '
    $between = /^\(/ .. /^\)/;
    push @buff, $_ if $between && /^\s/;
    print "(\n", sort splice(@buff), ")\n" if $between =~ /E/;
    print unless $between
   ' -- file.sql
  • -n逐行读取输入行
  • 如果您在行的开头()之间,则
  • $ between为真。
  • 从括号之间的空格开始的行被推送到缓冲区。
  • 当读取块的最后一行时,缓冲区被排序,打印和清空。
  • 直接打印其他行。