AWK: анализ аргументов в цикле
Я пытаюсь написать простой скрипт, который будет отображать поля, указанные пользователем в качестве аргументов bash. Например, у меня есть текстовый файл выглядит так:
1 2 3 4 5
1 2 3 4 5
a b c d e
И, например, типы пользователей:
./script.sh text 1 2 5
Где $1 = текст, а другие параметры (например, $2 $3 и $4) являются полями, поэтому вывод будет выглядеть следующим образом:
1 2 5
1 2 5
a b e
У меня есть этот код, который печатает все столбцы, определенные как аргументы, но один ниже других:
#!/bin/bash
text="$1"
shift
for x in $@; do
awk '{print $var}' var="$x" $text
done
Выведите для примера./script.sh текст 1 2 5:
1
1
a
2
2
b
5
5
e
Я думаю, что вывод выглядит так, потому что цикл "для" находится за пределами AWK. Это хорошее решение для этой задачи, чтобы поместить цикл внутри AWK? Я пробовал несколько вещей, но у меня всегда были проблемы с синтаксисом.
Спасибо за ваше время и помощь!
2 ответа
Вам не нужно перебирать параметры, передавать их всем awk
с -v
опция:
awk -v v1=$2 -v v2=$3 -v v3=$4 '{print $v1, $v2, $v3;}' $1
Вы можете выполнить дополнительные проверки, такие как файл ($1
) содержит достаточно полей, файл ($1
) существует и т. д. Но идея та же.
В вашем коде вы читаете файл несколько раз, каждый из которых проверяет только определенное поле, но для получения желаемого результата каждая строка должна быть проверена на наличие нескольких полей одновременно.
Передайте столбцы в awk, разбейте их на массив и напечатайте столбец, соответствующий каждому значению в массиве:
file=$1
shift
p="$@"
awk -v l="$p" '{t=split(l,a," "); for (i=1;i<=t;i++) printf $(a[i]) " ";printf "\n";}' $file
file="$1"
shift
awk -v flds="$*" 'BEGIN{n=split(flds,f)} {for (i=1;i<=n;i++) printf "%s%s", $(f[i]), (i<n?OFS:ORS)}' "$file"