至awk的管道(Bash)
此代码适用于:至awk的管道(Bash),awk,Awk,此代码适用于: #!bin/bash ad="J Dt, K R, P MA A F, E B, R VA O T, O R, T OK E A, P Rd, S MA H S, B R, R MA" byState() { a="$ad" h=$(echo "$a" | sed -e 's/ MA/, Massachusetts/' | sed -e 's/ OK/, Oklahoma/' | sed -e 's/ VA/, Virginia/') h=$(e
#!bin/bash
ad="J Dt, K R, P MA
A F, E B, R VA
O T, O R, T OK
E A, P Rd, S MA
H S, B R, R MA"
byState() {
a="$ad"
h=$(echo "$a" |
sed -e 's/ MA/, Massachusetts/' | sed -e 's/ OK/, Oklahoma/' | sed -e 's/ VA/, Virginia/')
h=$(echo "$h" | awk -F, '{print $4 ", " $0}' $* | sort)
... following code
echo "$h"
}
byState
但是如果在函数byState
中,我将a=“$ad”
替换为a=“$1”
并调用byState“$ad”
我得到
awk:fatal:无法打开文件“J”进行读取(没有这样的文件或目录)
有人能解释这种不同的行为吗?
awk-F,{script}$*
在函数byState()中,
在分词和全局化之后获取函数的参数,并将其用作awk
的参数,而awk
处理参数(当用作脚本时,除first外,任何形式的name=value都被视为赋值)作为要处理的文件名,首先打开它们。由于第一个标记是J
,并且显然在当前打开的目录中没有名为J
的文件,因此会出现错误
如果要使用
byState()
的第一个参数中的数据作为awk
的输入,请执行以下操作
echo "$1" | awk -F, '{script}' # with NO OTHER ARGS to awk
或者更好
printf '%s\n' "$1" | ...
# which reliably won't mangle backslashes and some dashes
或者在支持它的外壳上更好(您没有识别您的)
awk-F,“{script}”您能给我们看一下示例输入文件和预期输出吗?当问题清楚时,我们可以尝试提供帮助。您打算在awk命令中使用$*
什么?没有输入文件,只有一个字符串。我想使用按状态“$1”来输入
ieI的实际意思是,尽管你告诉我们有些东西不起作用,但如果可能的话,你可以通过几个例子让我们知道你想要实现的目标的全部情况,这样我们就可以尝试帮助你。我想让马萨诸塞州,EA,PR,S,马萨诸塞州,H S,B R,R,马萨诸塞州,J Dt,K R,P,马萨诸塞州,俄克拉何马州,O T,O R,T,俄克拉何马州弗吉尼亚州,A F,E B,R,弗吉尼亚州
,不幸的是,没有太多的空间来举例说明。目的是让州政府订购“$ad”。我明白你的意思(而且我是个初学者……)但是为什么代码在第一种情况下有效,而在第二种情况下无效。每种情况下的数据都是相同的。我没有询问如何正确操作,因为我担心有人会告诉我他不是来做我的工作的:-)我想我解决这个问题的方法是将echo“$h”
替换为printf“%s'$h”…
,感谢您的帮助。@user3166747这与您遇到的问题完全无关,并引入了一个新问题,因为echo“$h”
输出一行,该行以换行符结尾,该换行符是一个有效的POSIX文本行,而printf“%s'$h”
输出没有尾随换行符的文本,后续工具可能会也可能不会“正确”处理该文本,因为没有终止换行符的文本在POSIX中无效,因此您依赖于未定义的行为。您最初的问题仅仅是由于某种原因,您在awk命令的末尾卡住了$*
。是的,我也尝试了echo
,同时删除了$*
,它也起了作用。然而,我还不明白为什么代码在第一种情况下有效,而在第二种情况下无效:-(谢谢你的帖子。@user3166747:正如我在第一节中所说的,EdMorton重复了一遍,你的问题是$*
,它告诉awk
将数据的标记(从J
开始)作为要处理的文件名列表。
awk -F, '{script}' <<<"$1"