Rad*_* Rk 5 shell-script text-processing
我正在尝试编写一个脚本,通过将起始列、增量值和文件名作为运行时参数来打印文件的每 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
Run Code Online (Sandbox Code Playgroud)
我无法得到结果。任何人都可以帮助我吗?我的输入可以像script.sh file_name 1 4
提前致谢。:-)
壳牌变量不会自动地成为awk变量(也awk,变量表示var,不$var也就是var个领域)。如果要将 shell 变量传递给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"
Run Code Online (Sandbox Code Playgroud)
请记住引用您的 shell 变量,awk并且不能将任意文件名作为参数(因为它会处理其中一些带有 a=或-专门调用的文件名)。
将变量传递给的另一种方法awk是在 awk 脚本之后使用-v awkvar="$shellvar"或awkvar="$shellvar"参数,但这些不能用于任意字符串,因为转义序列在其中展开(例如\\变成\和\n变成换行符)和 GNU awk4.2 或更高版本,值@//除非在 POSIX 模式下,否则开头和结尾的会被特殊对待。
awk -v st="$st" -v inc="$inc" '{for (i = st; i <= NF; i += inc)...}' < "$file"
Run Code Online (Sandbox Code Playgroud)
或者
awk '{for (i = st; i <= NF; i += inc)...}' st="$st" inc="$inc" < "$file"
Run Code Online (Sandbox Code Playgroud)
在这里没问题,因为这些变量只包含数字(所以没有反斜杠)。
无论你做什么,不要做:
awk 'for (i = '"$st"'; i <= NF; i += '"$inc"')...'
Run Code Online (Sandbox Code Playgroud)
更别说
awk 'for (i = '$st'; i <= NF; i += '$inc')...'
Run Code Online (Sandbox Code Playgroud)
那就是让 shell 扩展传递给 的代码中$st和$inc变量的值awk,因为这会产生命令注入漏洞(例如对于stlike 的值system("reboot"))。