Расставить столбцы используя awk или sed?

У меня есть файл, который имеет около 500 строк и столбцов 480K, мне нужно переместить столбцы 2,3 и 4 в конце. Мой файл - файл, разделенный запятыми, есть ли более быстрый способ организовать это с помощью awk или sed?

5 ответов

Решение

Вы можете попробовать ниже решение -

perl -F"," -lane 'print "@F[0]"," ","@F[4..$#F]"," ","@F[1..3]"' input.file

Другая техника, просто bash:

while IFS=, read -r a b c d e; do
    echo "$a,$e,$b,$c,$d"
done < file

Возможно, Perl:

perl -F, -lane 'print join(",", @F[0,4..$#F,1,2,3])' file

или же

perl -F, -lane '@x = splice @F, 1, 3; print join(",", @F, @x)' file

Другой подход: регулярные выражения

perl -lpe 's/^([^,]+)(,[^,]+,[^,]+,[^,]+)(.*)/$1$3$2/' file

Синхронизация с файлом из 500 строк, каждая строка содержит 480000 полей

$ time perl -F, -lane 'print join(",", @F[0,4..$#F,1,2,3])' file.csv > file2.csv
40.13user 1.11system 0:43.92elapsed 93%CPU (0avgtext+0avgdata 67960maxresident)k
0inputs+3172752outputs (0major+16088minor)pagefaults 0swaps

$ time perl -F, -lane '@x = splice @F, 1, 3; print join(",", @F, @x)' file.csv > file2.csv
34.82user 1.18system 0:38.47elapsed 93%CPU (0avgtext+0avgdata 52900maxresident)k
0inputs+3172752outputs (0major+12301minor)pagefaults 0swaps

И чистая текстовая манипуляция - победитель

$ time perl -lpe 's/^([^,]+)(,[^,]+,[^,]+,[^,]+)(.*)/$1$3$2/' file.csv > file2.csv
4.63user 1.36system 0:20.81elapsed 28%CPU (0avgtext+0avgdata 20612maxresident)k
0inputs+3172752outputs (0major+149866minor)pagefaults 0swaps

Тестирование с 5 полями:

$ cat foo
1,2,3,4,5
a,b,c,d,e
$ cat program.awk
{
    $6=$2 OFS $3 OFS $4 OFS $1  # copy fields to the end and $1 too
    sub(/^([^,],){4}/,"")       # remove 4 first columns
    $1=$5 OFS $1                # catenate current $5 (was $1) to $1 
    NF=4                        # reduce NF
} 1                             # print

Запустить его:

$ awk -f program.awk FS=, OFS=, foo
1,5,2,3,4
a,e,b,c,d

Так что теоретически это должно работать:

{
    $480001=$2 OFS $3 OFS $4 OFS $1
    sub(/^([^,],){4}/,"")
    $1=$480000 OFS $1
    NF=479999 
} 1

РЕДАКТИРОВАТЬ: Это сработало.

Вы можете легко скопировать столбцы, перемещение для 480K столбцов займет слишком много времени.

$ awk 'BEGIN{FS=OFS=","} {print $0,$2,$3,$4}' input.file > output.file

что это за формат данных?

Другие вопросы по тегам