Вывод каждого столбца N из ввода

Я пытаюсь написать сценарий для печати всех N столбцов файла, указав начальный столбец, инкрементное значение и имя файла в качестве параметров времени выполнения. Ниже мой сценарий:

file=$1 st=$2 inc=$3 echo $file echo $st echo $inc awk '{for (i = $st; i <= NF; i += $inc) printf ("%s%c", $i, i + $inc <= NF ? " " : "\n");}' $file 

Я не могу получить результат. Может ли кто-нибудь мне помочь? Мои входы могут быть похожими на script.sh file_name 1 4

Заранее спасибо.:-)

  • Переменные в ksh
  • Объяснение вывода скрипта
  • Найти шаблон между специальными символами
  • Увеличение переменной с помощью скрипта Bash
  • Исправление или альтернатива для mktemp в OS X
  • Список файлов + каталог, рекурсивно отсортированный по времени доступа
  • Скрипт, запущенный daemon, не может найти общую библиотеку
  • Подстановка Bash с переменной, определенной из шаблона glob
  • 2 Solutions collect form web for “Вывод каждого столбца N из ввода”

    Переменные оболочки не автоматически становятся awk переменными (также в awk переменные выражаются как var , а не $var которые являются var ым полем). Если вы хотите передать переменную оболочки awk , простой подход заключается в использовании среды:

     #! /bin/sh - file=$1 ST=$2 INC=$3 export ST INC awk ' { sep = "" for (i = ENVIRON["ST"]; i <= NF; i += ENVIRON["INC"]) { printf "%c%s", sep, $i sep = OFS } printf "\n" }' < "$file" 

    Не забудьте указать ваши переменные оболочки и что awk не может получить произвольные имена файлов в качестве аргумента (так как он относится к некоторым из тех, у кого есть = в них или один - специально).

    Альтернативой для передачи переменных в awk является использование -v awkvar="$shellvar" или awkvar="$shellvar" после awk-скрипта, но они не могут использоваться для произвольных строк, поскольку в них расширяются escape-последовательности ( \\ становится \ и \n становится, например, новой строкой).

     awk -v st="$st" -v inc="$inc" '{for (i = st; i <= NF; i += inc)...}' < "$file" 

    или

     awk '{for (i = st; i <= NF; i += inc)...}' st="$st" inc="$inc" < "$file" 

    здесь все будет в порядке, поскольку эти переменные предназначены только для обозначения чисел (поэтому нет обратной косой черты).

    Что бы вы ни делали, не делайте:

     awk 'for (i = '"$st"'; i <= NF; i += '"$inc"')...' 

    не говоря уже о

     awk 'for (i = '$st'; i <= NF; i += '$inc')...' 

    то есть оболочка расширяет значения переменных $st и $inc в коде, переданном awk , поскольку это приводит к уязвимостям ввода команд (например, для значений st подобной system("reboot") ).

    Я скорректировал ваш скрипт так, что теперь он работает. Были две ошибки. (a) вам необходимо передать переменные оболочки в awk вручную (это делается с использованием -v awk_var="$shell_var" ) и (b) вы не должны использовать $ для обозначения переменной, знак $ используется только для позиции поля.

     file=$1 st=$2 inc=$3 echo $file echo $st echo $inc awk -v st="$st" -v inc="$inc" '{for (i = st; i <= NF; i += inc) printf ("%s%c", $i, i + inc <= NF ? " " : "\n");}' $file 
    Linux и Unix - лучшая ОС в мире.