Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 按匹配模式对文件行进行排序_Bash_Sorting_Awk - Fatal编程技术网

Bash 按匹配模式对文件行进行排序

Bash 按匹配模式对文件行进行排序,bash,sorting,awk,Bash,Sorting,Awk,输入 这是文件test.txt this is row4 row4 row2 xxx row2 row11 // row11 row10 mmm row10 row8row8 fubar row1row1 row6 and row6 row7 row7 row3row3 /row9 row9 row5 /row5 row1row1 row2 xxx row2 row3row3 this is row4 row4 row5 /row5 row6 and row6 row7 row7

输入

这是文件
test.txt

this is row4 row4
row2 xxx row2
row11 // row11
row10 mmm row10
row8row8 fubar
row1row1
row6 and row6
row7 row7
row3row3
/row9 row9
row5  /row5
row1row1    
row2 xxx row2
row3row3
this is row4 row4
row5  /row5
row6 and row6
row7 row7
row8row8 fubar
/row9 row9
row10 mmm row10
row11 // row11
在每一行上,都有该行应放置位置的指示。例如,当前第9行包含字符串“row3row3”,这意味着第9行应放置在位置3。每一行包含两倍的行位置指示,并且没有两行具有相同的索引

预期产出

下面是
test2.txt上的预期输出

this is row4 row4
row2 xxx row2
row11 // row11
row10 mmm row10
row8row8 fubar
row1row1
row6 and row6
row7 row7
row3row3
/row9 row9
row5  /row5
row1row1    
row2 xxx row2
row3row3
this is row4 row4
row5  /row5
row6 and row6
row7 row7
row8row8 fubar
/row9 row9
row10 mmm row10
row11 // row11
你能帮我把文件正确地分类吗

我尝试的

这是到目前为止对我的审判。我想我不太远,但有一个bug我没能找到

# Get the rows indication
a=$(grep -o row[0-9]* test.txt | sed s/row//)
a=( $a )

# Remove the double indication
a2=()
for i in $(seq 1 ${#a[@]})
do
[ $(($i%2)) -ne 0 ] && a2+=(${a[i]})
done

# Loop through each row
for row in $(seq 1 ${#a2[@]})
do
    # Search for the row that should be placed at position $row
    for i in "${!a2[@]}"; do
        if [[ "${a2[$i]}" = "${row}" ]]
        then
            # Once the correct row was found, read it and print it on another file
            p=$(sed "${a2[$i]}q;d" test.txt)
            echo $p >> test2.txt
            break
        fi
    done 
done

使用gnu
awk
您可以在一个命令中完成此操作:

awk -F '.*row' 'BEGIN {
   PROCINFO["sorted_in"] = "@ind_num_asc"
}
{
   a[$2] = $0
}
END {
   for(k in a)
      print a[k]
}' file
  • 使用自定义字段分隔符
    *行
    我们提取每行
    后的数字
  • 使用该数字作为键,我们创建一个数组
    a
    ,其中值为整行
  • PROCINFO[“sorted_in”]=“@ind_num_asc”
    用于按数组索引的升序对关联数组进行排序
输出:

row1row1
row2 xxx row2
row3row3
this is row4 row4
row5  /row5
row6 and row6
row7 row7
row8row8 fubar
/row9 row9
row10 mmm row10
row11 // row11

使用gnu
awk
您可以在一个命令中完成此操作:

awk -F '.*row' 'BEGIN {
   PROCINFO["sorted_in"] = "@ind_num_asc"
}
{
   a[$2] = $0
}
END {
   for(k in a)
      print a[k]
}' file
  • 使用自定义字段分隔符
    *行
    我们提取每行
    后的数字
  • 使用该数字作为键,我们创建一个数组
    a
    ,其中值为整行
  • PROCINFO[“sorted_in”]=“@ind_num_asc”
    用于按数组索引的升序对关联数组进行排序
输出:

row1row1
row2 xxx row2
row3row3
this is row4 row4
row5  /row5
row6 and row6
row7 row7
row8row8 fubar
/row9 row9
row10 mmm row10
row11 // row11
试试这个:

tr -c '0-9\n' ' ' <file | awk '{print $1}' | paste -d " " - file | sort -k1,1n | cut -d " " -f 2-
tr-c'0-9\n''

tr -c '0-9\n' ' ' <file | awk '{print $1}' | paste -d " " - file | sort -k1,1n | cut -d " " -f 2-

tr-c'0-9\n''”您可以始终遵循装饰/排序/取消装饰模式

$ sed -r 's/.*row([0-9]+)/\1\t&/' rows | sort -n | cut -f2-

row1row1
row2 xxx row2
row3row3
this is row4 row4
row5  /row5
row6 and row6
row7 row7
row8row8 fubar
/row9 row9
row10 mmm row10
row11 // row11

您可以始终遵循装饰/排序/取消装饰模式

$ sed -r 's/.*row([0-9]+)/\1\t&/' rows | sort -n | cut -f2-

row1row1
row2 xxx row2
row3row3
this is row4 row4
row5  /row5
row6 and row6
row7 row7
row8row8 fubar
/row9 row9
row10 mmm row10
row11 // row11
Perl解决方案:

perl -nle 'push @a, $_ ; 
 END{print join("\n", map  { $_->[0] }
 sort { $a->[1] <=> $b->[1] }
 map  { [$_, /(\d+)/] } @a)}' file
perl-nle'push@a,$\;
结束{print join(“\n”,映射{$\->[0]}
排序{$a->[1]$b->[1]}
映射{[$},/(\d+/]}@a)}文件
Perl解决方案:

perl -nle 'push @a, $_ ; 
 END{print join("\n", map  { $_->[0] }
 sort { $a->[1] <=> $b->[1] }
 map  { [$_, /(\d+)/] } @a)}' file
perl-nle'push@a,$\;
结束{print join(“\n”,映射{$\->[0]}
排序{$a->[1]$b->[1]}
映射{[$},/(\d+/]}@a)}文件

谢谢您的回答。我还没有完全理解它。请注意,对于我来说,标志
-r
似乎是一个非法选项。我还想知道什么对象是
。它是文件中的一个行数组(相当于我的数组
a
)?这是在“\1”位置插入匹配正则表达式的正则表达式标志。“行”是指示订购位置的数字的前缀。谢谢您的回答。我还没有完全理解它。请注意,对于我来说,标志
-r
似乎是一个非法选项。我还想知道什么对象是
。它是文件中的一个行数组(相当于我的数组
a
)?这是在“\1”位置插入匹配正则表达式的正则表达式标志。“行”是指示订购位置的编号前缀。谢谢!我试过你的代码,但它在我的计算机上没有完全按顺序排列。输出顺序为
8,2,3,4,5,6,7,9,10,11,1
。知道发生了什么吗?我将shell的命令输出附加到命令输出。你确定你在使用Gnu awk吗?如果你没有Gnu awk,那么就使用:
awk-F'.*行'{a[$2]=$0}END{for(k in a)print k,a[k]}'file | sort-nk1 | cut-d'.-f2-
谢谢你的评论。我想我最好默认链接gnu awk。谢谢!我试过你的代码,但它在我的计算机上没有完全按顺序排列。输出顺序为
8,2,3,4,5,6,7,9,10,11,1
。知道发生了什么吗?我将shell的命令输出附加到命令输出。你确定你在使用Gnu awk吗?如果你没有Gnu awk,那么就使用:
awk-F'.*行'{a[$2]=$0}END{for(k in a)print k,a[k]}'file | sort-nk1 | cut-d'.-f2-
谢谢你的评论。我想我最好默认链接gnu awk。