至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"