我绑定了一组管道命令的别名,浏览了这里的一些线程,发现 cmd 行应该以不同的方式使用。使用 !:1 而不是 $1 但它在以下上下文中似乎对我不起作用
这是我想要别名的一组命令(其计算中位数)
shell> cat file_with_numbers| awk '{print $1}' | sort -n | awk ' { a[i++]=$1; } END { x=int((i+1)/2); if (x < (i+1)/2) print (a[x-1]+a[x])/2; else print a[x-1]; }'
shell> 1.15
我想将下面的部分别名为“中位数”
sort -n | awk ' { a[i++]=$1; } END { x=int((i+1)/2); if (x < (i+1)/2) print (a[x-1]+a[x])/2; else print a[x-1]; }'
所以我可以用
shell> cat file_with_numbers| awk '{print $1}' | median
alias median 'sort -n | awk ' { a[i++]=$1; } END { x=int((i+1)/2); if (x < (i+1)/2) print (a[x-1]+a[x])/2; else print a[x-1]; }''
() 的位置不好。 //单引号错误
alias median "sort -n | awk ' { a[i++]=$1; } END { x=int((i+1)/2); if (x < (i+1)/2) print (a[x-1]+a[x])/2; else print a[x-1]; }'"
cat file| awk '{print $5}'| median
awk: { a[i++]=; } END { x=int((i+1)/2); if (x < (i+1)/2) print (a[x-1]+a[x])/2; else print a[x-1]; }
awk: ^ syntax error
所以我切换到\!:1
并尝试了以下方法,但它仍然不起作用。我怎样才能正确地使用这个别名?
1> 试验1
alias median "sort -n | awk ' { a[i++]=\!:1; } END { x=int ( ( i+1 ) /2 ) ; if ( x < ( i+1 ) /2 ) print ( a[x-1]+a[x] ) /2 ; else print a[x-1] ; }' "
cat file| awk '{print $5}' | median
Bad ! arg selector.
2> 审判2
alias median "sort -n | awk ' { a[i++]=\\!:1; } END { x=int ( ( i+1 ) /2 ) ; if ( x < ( i+1 ) /2 ) print ( a[x-1]+a[x] ) /2 ; else print a[x-1] ; }' "
cat file| awk '{print $5}' | median
awk: { a[i++]=!:1; } END { x=int ( ( i+1 ) /2 ) ; if ( x < ( i+1 ) /2 ) print ( a[x-1]+a[x] ) /2 ; else print a[x-1] ; }
awk: ^ syntax error
试用3>
答案1
您可以在别名中放置单行命令序列,但您可能需要到处添加反斜杠和单引号或双引号。但是,除非您需要使用 shell 历史记录中的参数或元素调用别名,或者需要最大限度地提高速度,否则有时将命令序列按原样放入文件中,将其标记为可执行文件,然后将其放置在您的文件中的某个位置会更容易。搜索路径($PATH
或$path
)。
但要使以下内容成为别名:
sort -n | awk '{ a[i++]=$1; } END { x=int((i+1)/2); if (x < (i+1)/2) print (a[x-1]+a[x])/2; else print a[x-1]; }'
你需要确保
- 管道运算符位于用引号引起来的字符串内;否则它将终止别名命令
- the
$
要么位于用单引号括起来的字符串内,要么位于任何带引号的字符串之外且前面带有 a\
(感谢 Stéphane,提供了替代方案) - 没有嵌套的单引号
不要用来\!:1
尝试生产$1
.\!:1
如果您将参数传递给别名,则会使用它。你只是想让$1
awk 看到文字。
在这种情况下,最安全的做法是用单引号将尽可能多的别名括起来,并且"
仅用于包围文字单引号。您将看到下面出现两次"'"
。
ubuntu% alias median 'sort -n | awk '"'"'{ a[i++]=$1 ; } END { x=int ( ( i+1 ) /2 ) ; if ( x < ( i+1 ) /2 ) print ( a[x-1]+a[x] ) /2 ; else print a[x-1] ; }'"'"
ubuntu% seq 1 9 | median
5
答案2
除非你关心重新发明轮子,否则你也可以使用 GNU datamash
:
alias median 'datamash median 1'
datamash
需要制表符分隔的列,尽管您可以使用 更改分隔符-t
。
对于您的特定问题,请注意$parameter
(t)csh 中的扩展是在双引号内完成的,但与类似 Bourne 的 shell 相反,它不能用反斜杠禁用,因此您需要类似的内容:
alias median "sort -n | awk '{a[NR]="\$"1}; END {x = int(NR/2); print NR % 2 ? a[x+1] : (a[x]+a[x+1])/2}'"
也就是说,摆脱双引号来输入$
as \$
,或者采用 Mark 的方法并使用单引号,但摆脱双引号来输入文字单引号。
答案3
尝试这个:
$ alias median="sort -n|awk ' { a[i++]="\$1"; } END { x=int((i+1)/2); if (x < (i+1)/2) print (a[x-1]+a[x])/2; else print a[x-1]; }'"
$ cat file_with_numbers| awk '{print $1}'|median