Ваша интерполированная переменная $cols
выглядит так, как будто она должна быть числом, скажем, 10, поэтому
"%${cols}s"
должно интерполироваться и быть эквивалентным
"%10s"
, которая является допустимой строкой формата.
Если бы $cols
было чем-то другим , чем число или допустимая строка формата, вы получите предупреждение.
Например, если:
$cols = "w";
, что приведет к "%ws"
в качестве строки формата - с ошибкой, которую вы цитируете:
Invalid conversion in printf: "%w"
Информация о правильном формате может быть найдена здесь .