在bash中以特定顺序打印文件内容

时间:2019-02-05 15:29:21

标签: bash shell awk sed

我有两个文件。我在file1上执行了一些操作,生成了另一个文件file2

这是我的file1内容:

class parent {
   public void bye() {statement}   
   public void home1() {statement}
   public void Work() {statement}       
   public void apple() {statement}      
   public void fruits() {statement} 
  }

这是我制作的file2内容:

parent
{
        void parent.<init>() (dex_method_idx=8)  {statement}
        void parent.Work() (dex_method_idx=13) {statement}       
        void parent.apple() (dex_method_idx=9) {statement} 
        void parent.bye() (dex_method_idx=10) {statement} 
        void parent.fruits() (dex_method_idx=11) {statement} 
        void parent.home1() (dex_method_idx=12) {statement} 
}

具有固定模式的生成的file2。第一个功能代码将始终是init段落。然后它将打印以大写字母(例如工作)开头的功能代码。然后按字母顺序打印其余功能代码。

如何根据file2功能代码的顺序打印file1功能代码。 预期输出:

parent
{
        void parent.<init>() (dex_method_idx=8)  {statement}    
        void parent.bye() (dex_method_idx=10) {statement} 
        void parent.home1() (dex_method_idx=12) {statement}
        void parent.Work() (dex_method_idx=13) {statement}       
        void parent.apple() (dex_method_idx=9) {statement} 
        void parent.fruits() (dex_method_idx=11) {statement}        
}

请给我建议一种方法。

4 个答案:

答案 0 :(得分:3)

$ cat tst.awk
BEGIN { FS="[^[:alnum:]_]+" }
NR==FNR {
    if (/^[[:space:]]*}[[:space:]]*$/) { inDefs=0 }
    if (inDefs) { map[$4] = $0 }
    if (/^[[:space:]]*{[[:space:]]*$/) { inDefs=1 }
    next
}
FNR==1 {
    print $2 ORS "{"
    print map["init"]
    next
}
{ print ($4 in map ? map[$4] : $0) }

$ awk -f tst.awk file2 file1
parent
{
        void parent.<init>() (dex_method_idx=8)  {statement}
        void parent.bye() (dex_method_idx=10) {statement}
        void parent.home1() (dex_method_idx=12) {statement}
        void parent.Work() (dex_method_idx=13) {statement}
        void parent.apple() (dex_method_idx=9) {statement}
        void parent.fruits() (dex_method_idx=11) {statement}
  }

答案 1 :(得分:2)

  

当我执行以上代码时,它仅显示文件1的内容
  它没有显示在输出上方

这可能是由于拥有不知道字符类awk[:alnum:])的POSIX前[:space:]。这是埃德·莫顿(Ed Morton)的不含字符类的脚本的版本:

BEGIN { FS="[ .]+" }
NR==FNR {
    if (/^ *} *$/) inDefs=0
    if (inDefs) map[$4] = $0
    if (/^ *{ *$/) inDefs=1
    next
}
FNR==1 {
    print $2 ORS "{"
    print map["<init>()"]
    next
}
{ print $4 in map ? map[$4] : $0 }

答案 2 :(得分:1)

我不知道您输入文件的变体。该解决方案适用于您的示例。

您要搜索file1的功能。

grep -o "[^ ]*()"  file1

前三行和最后一行是特殊的。
将它们与

结合
sed -n '1,3 p' file2
grep -f <(grep -o "[^ ]*()"  file1) file2
sed -n '$ p' file2

答案 3 :(得分:1)

与AWK的另一种方法:

awk -vl=1 '
NR==FNR {
if ($3 ~ /[(][)]$/) {
    a[$3]=++j
    }
next
}
{ split($2,e," ") }
!(e[1] in a) {
  print
  next
}
{
  d[a[e[1]]]=$0
  while ( d[l] != "" ) {
    print d[l]
    l++
    }
  }
' file1 FS=\. file2