Относительно вашей конкретной проблемы, фрагмент:
awk '{print substr($1,$num,21)}' $input
имеет проблему, заключающуюся в том, что внутри одинарных кавычек есть , а не в зависимости от расширения переменной оболочки. Это можно увидеть с помощью:
pax$ num=42 && echo '$num'
$num
pax$ num=42 && echo "$num"
42
Следовательно, $num
будет не заменено значением переменной оболочки.
Как также видно выше, вы можете использовать двойные кавычки, которые позволят разрешить расширение, но тогда вам нужно экранировать $1
до , чтобы предотвратить его расширение. Обычно мне проще превратить переменные оболочки в переменные awk
, например:
awk -vnum=$num '{print substr($1,num,21)}' $input
Следующий фрагмент показывает это в действии:
pax$ num=42 && awk 'END{print $num}' </dev/null
pax$ num=42 && awk -v num=$num 'END{print num}' </dev/null
42
Однако 17 000 вызовов внешней программы будут довольно неэффективными, вам лучше скомпилировать что-нибудь или, если вам нужно использовать сценарии, это можно сделать полностью в самом bash
. Приведенный ниже код показывает, как вы можете это сделать, важный бит находится в блоке time ( )
, все остальное - просто настройка тестовых данных, синхронизация и очистка.
# Create test data.
(
for i in {1..1000} ; do
echo -n "abcdefghijklmnop-"
done
) >inputdata.txt
# Time the execution.
time (
char17k="$(cat inputdata.txt)"
echo ${#char17k}
for ((i = 0; i < ${#char17k}; i++)) ; do
echo ${char17k:i:21}
done
)
# Clean up.
rm -rf inputdata.txt
В моей системе это завершается примерно через десять секунд. Время, затрачиваемое на 17 000 awk
вызовов, примерно в три раза больше, даже без выполнения какой-либо полезной работы:
pax$ time (for in in {1..17000} ; do awk '{}' </dev/null ; done )
real 0m30.649s
user 0m5.196s
sys 0m4.848s
Конечно, вы можете получить даже больше скорости, дав awk
делать все работу. Замена содержимого блока time ( )
в приведенном выше коде на:
awk '{for (i = 1; i < length($0); i++) {print substr($0, i, 21)}}' inputdata.txt
дает гораздо более впечатляющее (около десятой доли секунды):
real 0m0.121s
user 0m0.008s
sys 0m0.016s