Reputation: 18239
Input
Here is the file 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
On each row, there is the indication of where the row should be placed. For example, the current row 9 contains the string "row3row3", this means that the row 9 should be placed at position 3. Each row contains exactly twice the indication of where the row should be placed and no two rows have the same index.
Expected Output
Here is the expected output on test2.txt
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
Can you help me to sort the file correclty?
What I tried
Here is my trial so far. I think I am not too far but there is a bug I fail to find.
# 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
Upvotes: 1
Views: 502
Reputation: 104092
Perl solution:
perl -nle 'push @a, $_ ;
END{print join("\n", map { $_->[0] }
sort { $a->[1] <=> $b->[1] }
map { [$_, /(\d+)/] } @a)}' file
Upvotes: 0
Reputation: 67567
You can always follow decorate/sort/undecorate pattern
$ 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
Upvotes: 2
Reputation: 88969
Try this:
tr -c '0-9\n' ' ' <file | awk '{print $1}' | paste -d " " - file | sort -k1,1n | cut -d " " -f 2-
Upvotes: 1
Reputation: 786101
Using gnu awk
you can do this in a single command:
awk -F '.*row' 'BEGIN {
PROCINFO["sorted_in"] = "@ind_num_asc"
}
{
a[$2] = $0
}
END {
for(k in a)
print a[k]
}' file
.*row
we extract the number after row
for each linea
where value is full linePROCINFO["sorted_in"] = "@ind_num_asc"
is used to sort associative array in ascending numerical order of array indexOutput:
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
Upvotes: 3