按给定顺序重新排序文件行

时间:2013-03-26 14:42:04

标签: bash file-io

我有一个文件 A ,其中包含 n 行。我还有一系列 n 整数,所有这些都是唯一的并且< n 。我的目标是创建一个文档 B ,它与 A 具有相同的内容,但是根据给定的顺序使用重新排序的行。

示例:

A

Foo
Bar
Bat

序列:2,0,1(意思是:第一行2,然后第0行,然后是第1行)

输出( B ):

Bat
Foo
Bar

提前感谢您的帮助

4 个答案:

答案 0 :(得分:5)

另一种解决方案:

您可以通过执行创建序列文件(假设序列以逗号分隔):

echo $sequence | sed s/,/\\n/g > seq.txt

然后,就这样做:

paste seq.txt A.txt | sort tmp2.txt | sed "s/^[0-9]*\s//"

这是一个bash函数。订单可以由任何东西分隔。

用法:schwartzianTransform "A.txt" 2 0 1

function schwartzianTransform {
    local file="$1"
    shift
    local sequence="$@"
    echo -n "$sequence" | sed 's/[^[:digit:]][^[:digit:]]*/\
/g' | paste -d ' ' - "$file" | sort -n | sed 's/^[[:digit:]]* //'
}

答案 1 :(得分:1)

一种方式(对于大文件来说效率不高):

$ seq="2 0 1"
$ for i in $seq
> do
>   awk -v l="$i" 'NR==l+1' file
> done
Bat
Foo
Bar

如果您的文件很大,可以使用以下文件:

$ seq='2,0,1'
$ x=$(echo $seq | awk '{printf "%dp;", $0+1;print $0+1> "tn.txt"}' RS=,)
$ sed -n "$x" file | awk 'NR==FNR{a[++i]=$0;next}{print a[$0]}' - tn.txt

第二行准备一个sed命令打印指令,然后使用sed命令在第3行中使用。这仅打印序列中存在的行号,但不按序列的顺序打印。 awk命令用于根据序列对sed结果进行排序。

答案 2 :(得分:1)

将文件读入数组,然后使用索引功能:

echo "Enter the input file name"
read ip

index=0

while read line ; do
        NAME[$index]="$line"
            index=$(($index+1))
            done < $ip

echo "Enter the file having order"
read od

while read line ; do
        echo "${NAME[$line]}";
            done < $od

[aman@aman sh]$ cat test 
Foo
Bar
Bat
[aman@aman sh]$ cat od
2
0
1
[aman@aman sh]$ ./order.sh 
Enter the input file name
test
Enter the file having order
od
Bat
Foo
Bar

答案 3 :(得分:1)

awk oneliner可以完成这项工作:

 awk -vs="$s" '{d[NR-1]=$0}END{split(s,a,",");for(i=1;i<=length(a);i++)print d[a[i]]}'  file

$s是你的序列。

看看这个例子:

kent$  seq 10 >file  #get a 10 lines file

kent$  s=$(seq 0 9 |shuf|tr '\n' ','|sed 's/,$//') # get a random sequence by shuf

kent$  echo $s     #check the sequence in var $s
7,9,1,0,5,4,3,8,6,2 

kent$  awk -vs="$s" '{d[NR-1]=$0}END{split(s,a,",");for(i=1;i<=length(a);i++)print d[a[i]]}'  file                                                                          
8
10
2
1
6
5
4
9
7
3