将文件的最后一行捕获为整数变量并在 awk 命令中使用
capture last line of file as integer variable and use in awk command
我正在尝试捕获文件的最后一行作为 awk 命令中使用的变量。
这是文件的示例(文件结尾):
cat file.txt
....
phylum:Chlorophyta 1
phylum:Mucoromycota 1
column 6:
superkingdom:Eukaryota 99
column 7:
99
我想在 awk 命令中使用那个“99”作为整数,将其保存为变量,
tail -n1 file.txt
99
例如
div=$(tail -n1 file.txt)
echo $div
99
用于第二个文件 (conf.txt),用于划分第二个字段中的数字:
cat conf.txt
Class 88
Family 78
Genus 44
Species 23
但是,当我尝试在 awk 命令中使用 $div
变量时(使用 -v
标志,如此处和其他地方在获取变量时使用 awk 所建议的),我收到此错误:
awk -v a=$div '{print /a}' conf.txt
awk: can't open file {print /a}
source line number 1
但是当 99 只是在 cmd 行上作为一个变量时,它工作得很好:
num=99
awk -v a=$num '{print /a}' conf.txt
0.888889
0.787879
0.444444
0.232323
在 tail -1
的捕获中是否有额外的 spaces/characters?我遗漏了一些简单但基本的东西。
最后,我什至不想先保存为一个单独的变量如果我不需要,相反,只需捕获最后的行号 (99) 并直接放入 awk cmd,例如:
awk '{print /[tail -1 file.txt]}' conf.txt
这是伪代码(在括号中)...但是,这最终将是我想要的...
感谢您的帮助!
最后一行开头有一个space,所以命令变成
awk -v a= 99 '{print /a}' conf.txt
这是将 a
设置为空字符串,将 99
视为 awk 脚本,将其余部分视为文件名。
从 $div
中删除 space。
div=${div// /}
在 shell.
中使用引号作为一种习惯
鉴于:
cat file
blah blah
99
命令 n=$(tail -n1 file)
在 99:
前面生成前导 spaces
n=$(tail -n1 file)
printf "\"%s\"\n" "$n"
" 99"
当你 认为 你正在检查没有引号的 $n
的值时,它尤其是一个 bug,因为领先的 spaces 被删除shell 在调用 echo
.
之前
考虑:
echo $n # no quotes - leading spaces stripped
99
echo "$n" # preserve whitespace...
99
现在,如果您尝试将不带引号的参数传递给 awk,space 对 shell 有意义并搞砸命令的解释方式:
awk -v n=$n 'BEGIN{printf "\"%s\", %s\n", n, n+1}'
awk: fatal: cannot open file `BEGIN{printf "\"%s\", %s\n", n, n+1}' for reading: No such file or directory
对比:
awk -v n="$n" 'BEGIN{printf "\"%s\", %s\n", n, n+1}'
" 99", 100
如果你想用awk
代替tail
的使用,你可以使用FNR==NR
的习语来测试文件是否是第一个文件和==+0
测试 awk
是否将其视为数字:
awk 'FNR==NR {n=+0== ? +0 : n; next} # n ends up being the last number seen
==+0{print /n}
' file conf.txt
0.888889
0.787879
0.444444
0.232323
启用调试模式和运行 awk
命令:
$ set -x
$ awk -v a=$div '{print /a}' conf.txt
+ awk -v a= 99 '{print /a}'
awk: fatal: cannot open file `{print /a}' for reading: No such file or directory
感兴趣:
-v a=
- 定义 awk
变量 a
为空
99
- awk
code/script
'{print /a}'
- 传递给 awk
脚本的第一个文件,以及错误消息的来源
正如其他人所指出的,您可以通过将 $div
括在双引号中来解决该错误:
$ awk -v a="$div" '{print /a}' conf.txt
+ awk -v 'a= 99' '{print /a}' conf.txt
0.888889
0.787879
0.444444
0.232323
感兴趣:
-v '= 99'
- 定义 awk
变量 a
和字符串 ' 99'
- 在这种情况下,当变量的其余部分可以解释为数字时,
awk
忽略空格
'{print /a}'
- awk
code/script
conf.txt
- 文件传递给 awk
脚本
Barmar 和 dawg 分别解决了从 div
中剥离空白并在整个过程中使用 awk
的问题。
而不是让 shell 调用一些命令来获取 file.txt 的最后一行,然后将其保存在 shell 变量中,然后将 awk 变量设置为从中填充的相同值shell 变量并将其传递给 awk,只需调用一次 awk:
$ awk 'NR==FNR{n=; next} {print /n}' file.txt conf.txt
0.888889
0.787879
0.444444
0.232323
我正在尝试捕获文件的最后一行作为 awk 命令中使用的变量。
这是文件的示例(文件结尾):
cat file.txt
....
phylum:Chlorophyta 1
phylum:Mucoromycota 1
column 6:
superkingdom:Eukaryota 99
column 7:
99
我想在 awk 命令中使用那个“99”作为整数,将其保存为变量,
tail -n1 file.txt
99
例如
div=$(tail -n1 file.txt)
echo $div
99
用于第二个文件 (conf.txt),用于划分第二个字段中的数字:
cat conf.txt
Class 88
Family 78
Genus 44
Species 23
但是,当我尝试在 awk 命令中使用 $div
变量时(使用 -v
标志,如此处和其他地方在获取变量时使用 awk 所建议的),我收到此错误:
awk -v a=$div '{print /a}' conf.txt
awk: can't open file {print /a}
source line number 1
但是当 99 只是在 cmd 行上作为一个变量时,它工作得很好:
num=99
awk -v a=$num '{print /a}' conf.txt
0.888889
0.787879
0.444444
0.232323
在 tail -1
的捕获中是否有额外的 spaces/characters?我遗漏了一些简单但基本的东西。
最后,我什至不想先保存为一个单独的变量如果我不需要,相反,只需捕获最后的行号 (99) 并直接放入 awk cmd,例如:
awk '{print /[tail -1 file.txt]}' conf.txt
这是伪代码(在括号中)...但是,这最终将是我想要的...
感谢您的帮助!
最后一行开头有一个space,所以命令变成
awk -v a= 99 '{print /a}' conf.txt
这是将 a
设置为空字符串,将 99
视为 awk 脚本,将其余部分视为文件名。
从 $div
中删除 space。
div=${div// /}
在 shell.
中使用引号作为一种习惯鉴于:
cat file
blah blah
99
命令 n=$(tail -n1 file)
在 99:
n=$(tail -n1 file)
printf "\"%s\"\n" "$n"
" 99"
当你 认为 你正在检查没有引号的 $n
的值时,它尤其是一个 bug,因为领先的 spaces 被删除shell 在调用 echo
.
考虑:
echo $n # no quotes - leading spaces stripped
99
echo "$n" # preserve whitespace...
99
现在,如果您尝试将不带引号的参数传递给 awk,space 对 shell 有意义并搞砸命令的解释方式:
awk -v n=$n 'BEGIN{printf "\"%s\", %s\n", n, n+1}'
awk: fatal: cannot open file `BEGIN{printf "\"%s\", %s\n", n, n+1}' for reading: No such file or directory
对比:
awk -v n="$n" 'BEGIN{printf "\"%s\", %s\n", n, n+1}'
" 99", 100
如果你想用awk
代替tail
的使用,你可以使用FNR==NR
的习语来测试文件是否是第一个文件和==+0
测试 awk
是否将其视为数字:
awk 'FNR==NR {n=+0== ? +0 : n; next} # n ends up being the last number seen
==+0{print /n}
' file conf.txt
0.888889
0.787879
0.444444
0.232323
启用调试模式和运行 awk
命令:
$ set -x
$ awk -v a=$div '{print /a}' conf.txt
+ awk -v a= 99 '{print /a}'
awk: fatal: cannot open file `{print /a}' for reading: No such file or directory
感兴趣:
-v a=
- 定义awk
变量a
为空99
-awk
code/script'{print /a}'
- 传递给awk
脚本的第一个文件,以及错误消息的来源
正如其他人所指出的,您可以通过将 $div
括在双引号中来解决该错误:
$ awk -v a="$div" '{print /a}' conf.txt
+ awk -v 'a= 99' '{print /a}' conf.txt
0.888889
0.787879
0.444444
0.232323
感兴趣:
-v '= 99'
- 定义awk
变量a
和字符串' 99'
- 在这种情况下,当变量的其余部分可以解释为数字时,
awk
忽略空格 '{print /a}'
-awk
code/scriptconf.txt
- 文件传递给awk
脚本
Barmar 和 dawg 分别解决了从 div
中剥离空白并在整个过程中使用 awk
的问题。
而不是让 shell 调用一些命令来获取 file.txt 的最后一行,然后将其保存在 shell 变量中,然后将 awk 变量设置为从中填充的相同值shell 变量并将其传递给 awk,只需调用一次 awk:
$ awk 'NR==FNR{n=; next} {print /n}' file.txt conf.txt
0.888889
0.787879
0.444444
0.232323