Как использовать индексный фронт $ в цикле? - PullRequest
0 голосов
/ 13 июня 2019

Я борюсь с простой петлей.Я хочу получить:

awk '{print $3}' z.csv > col1.csv
awk '{print $4}' z.csv > col2.csv
...
awk '{print $(i+2)}' z.csv> col(i).csv

Вот что я попробовал до сих пор:

k=$i+2;
for i in {1..21}
do 
 awk '{print $k}' z.csv > col"${i}".csv
done 

Но это далеко не работает, любой совет, пожалуйста?

1 Ответ

5 голосов
/ 13 июня 2019

Нет необходимости в цикле bash, вызывающем awk несколько раз, просто цикл в 1 вызове awk, например, с GNU awk, который автоматически обрабатывает потенциальную проблему «слишком много открытых файлов»:

awk '{
    for (i=1; i<=21; i++) {
        print $(i+2) > ("col"i".csv")
    }
}' z.csv

и с любым awk:

awk '{
    for (i=1; i<=21; i++) {
        close(out)
        out = "col"i".csv"
        print $(i+2) >> out
    }
}' z.csv

Если закрытие всех файлов на каждой итерации вызывает проблемы с производительностью, и вы обнаружите, что вы можете, скажем, 11 выходных файлов открывать одновременно, не получая «слишком много открытых»файлы "ошибка, то вы можете сделать что-то вроде этого:

awk '{
    for (i=1; i<=21; i++) {
        if (i>11) close(out)
        out = "col"i".csv"
        print $(i+2) >> out
    }
}' z.csv

или чуть более эффективно, но с немного большим кодом:

awk '{
    for (i=1; i<=10; i++) {
        print $(i+2) > ("col"i".csv")
    }
    for (; i<=21; i++) {
        close(out)
        out = "col"i".csv"
        print $(i+2) >> out
    }
}' z.csv
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...