希望从文件“schemas.txt”中提取用户输入的第三个字段的位置
schemas="schemas.txt"
for i in ${schemas[@]};
do
awk '{for(i=1;i<=NF;i++)if($i=="$3")print i}'
done
关于为什么我陷入无限循环有什么想法吗?
编辑:添加了下面的示例。
在 schemas.txt 中,第二行是“人物身高体重年龄种族职业”
假设用户输入“age”作为第三个参数,我希望解析该行并返回“4”,因为它是字符串中的第四个单词。
答案1
如果我明白你的意图,我认为你不需要 shell 循环。相反,请为 awk 提供要在命令行上读取的文件的名称。我们可以传递关键字来查找 with -v
,它从命令行设置一个 awk 变量。
因此,对于包含“age”的每一行,这将打印出现的字段编号:
$ cat schemas.txt
People height weight age race occupation
age is first on this line
$ keyword=age
$ awk -vk="$keyword" '{ for (i = 1 ; i <= NF ; i++) if($i == k) print i }' schemas.txt
4
1
当然fixed关键字只是一个例子,你可以使用awk -vk="$3"
, 并跳过额外的变量。
一般来说,看起来打印行号也很有用,你可以用来print NR, i
这样做。
这里,
schemas="schemas.txt"
for i in ${schemas[@]};
do
awk '{for(i=1;i<=NF;i++)if($i=="$3")print i}'
done
schemas
仅包含schemas.txt
,因此这就是 shell 变量i
在循环中设置的内容。不过,它在循环中未使用,因此循环实际上并没有做太多事情。 awk 脚本中的i
独立于 shell i
。
awk
似乎挂在这里,因为默认情况下它从标准输入读取。另外,"$3"
不会被单引号内的 shell 扩展,因此 awk 会查找字面上包含$3
.
对于多个文件,循环会更有意义:
files=(file1.txt file2.txt)
for file in "${files[@]}"; do
awk '{...}' "$file"
done
但即便如此,您也可以一次性将所有文件传递给 awk:
awk '{...}' "${files[@]}"