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
使用gnuawk
您可以在一个命令中完成此操作:
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
使用gnuawk
您可以在一个命令中完成此操作:
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。