awk читает и разделяет заголовки из одного файла, использует его в других файлах

Попробуйте приведенное ниже решение awk:

echo "Hello" | awk '{ for ( i=length($0);i>0;i-- ) { if (i == length($0) ) { printf "%s",toupper(substr($0,i,1)) } else {  printf "%s",tolower(substr($0,i,1)) } } printf "\n" }'

Возьмите каждую букву слова посимвольно, начиная с последней. Если это последний символ, преобразуйте его в верхний регистр и напечатайте, иначе напечатайте нижний регистр.

0
09.09.2020, 16:20
2 ответа

Не совсем ответ, но слишком большой и требует форматирования, поэтому это не может быть комментарием, поэтому...

1.6M — это не так уж много строк. 1 миллион строк в час, как вы говорите, чрезвычайно медленный, 1 миллион строк в минуту был бы более чем разумным. Например, я создал файл длиной 1 600 000 строк, по 300 столбцов в каждой, запустив этот скрипт:

$ awk -v n=1600000 -v c=300 -v OFS='\t' 'BEGIN{for (j=1;j<=c;j++) printf "col%s%s",j,(j<c?OFS:ORS); for (i=1;i<=n;i++) for (j=1;j<=c;j++) printf "%s%s",j,(j<c?OFS:ORS)}' > file

а затем я запустил скрипт, чтобы выполнить преобразование в вашем вопросе в этом файле:

$ time awk 'BEGIN{FS=OFS="\t"} NR==1{split($0, headers); print; next} {for (i=166;i<=NF;i++) $i=headers[i] "|" $i } 1' file > out

real    1m22.569s
user    1m17.971s
sys     0m4.359s

Таким образом, это заняло около 82 секунд вместо 1,5 часов.

0
18.03.2021, 23:14

С GNU Parallel это выглядит примерно так:

#!/bin/bash

do_block() {
    awk 'BEGIN{FS=OFS="\t"}
     NR==1{split($0, headers); next}
     {for (i=166;i<=NF;i++) $i=headers[i] "|" $i } 1'
}
export -f do_block

# Non-parallel version
cat file | head -n1 > out1
time cat file | do_block >> out1

# Parallel version
cat file | head -n1 > out2
time parallel -k --pipepart --block -30 -a file --header : do_block >> out2

На моем 4-ядерном процессоре параллельная версия примерно в 3 раза быстрее.

0
18.03.2021, 23:14

Теги

Похожие вопросы