[英]Unix 'alias' fails with 'awk' command
I'm creating an alias in Unix and have found that the following command fails.. 我在Unix中创建了一个别名,发现以下命令失败了..
alias logspace='find /apps/ /opt/ -type f -size +100M -exec ls -lh {} \; | awk '{print $5, $9 }''
I get the following : 我得到以下内容:
awk: cmd. line:1: {print
awk: cmd. line:1: ^ unexpected newline or end of string
Any ideas on why the piped awk command fails... 关于为什么管道awk命令失败的任何想法......
Thanks, Shaun. 谢谢,肖恩。
To complement's @Dropout's helpful answer : 补充@ Dropout的有用答案 :
The problem is the OP's attempt to use '
inside a '
-enclosed (single-quoted) string. 问题是OP尝试使用
'
内部 '
封闭(单引号)字符串。
The most robust solution in this case is to replace each interior '
with '\\''
(sic): 在这种情况下, 最健壮的解决方案是替换每个内部
'
与'\\''
(原文如此):
alias logspace='find /apps/ /opt/ -type f -size +100M -exec ls -lh {} \; |
awk '\''{print $5, $9 }'\'''
'
chars inside single-quoted ( '...'
-enclosed) strings AT ALL - not even with escaping . '
(内单引号字符'...'
-enclosed)串在所有-即使不是逃避 。
"
inside a double -quoted string as \\"
, and, as in @Droput's answer, you can directly, embed '
chars. there, but see below for pitfalls.) "
双 -quoted字符串作为内部\\"
,并且,如@ Droput的回答,您可以直接嵌入'
字符。在那里,但请参阅下面的陷阱。) '
chars. '
字符”。 - escaped outside the single-quoted strings as \\'
- are spliced in . \\'
- 拼接在一起 。 '\\''
means: "close string", "escape single quote", "start new string". '\\''
表示:“关闭字符串”,“转单引号”,“启动新字符串”。 Other solutions and their pitfalls : 其他解决方案及其缺陷 :
The following discusses alternative solutions, based on the following alias: 以下讨论基于以下别名的替代解决方案:
alias foo='echo A '\''*'\'' is born at $(date)'
Note how the *
is effectively enclosed in single quotes - using above technique - so as to prevent pathname expansion when the alias is invoked later. 注意
*
如何有效地用单引号括起来 - 使用上面的技术 - 以便在以后调用别名时防止路径名扩展。
When invoked, this alias prints literal A * star is born
, followed by the then -current date and time, eg: A * is born at Mon Jun 16 11:33:19 EDT 2014
. 当被调用时,这个别名打印文字
A * star is born
,然后是当时的日期和时间,例如: A * is born at Mon Jun 16 11:33:19 EDT 2014
。
Use a feature called ANSI C quoting with shells that support it: bash
, ksh
, zsh
使用名为ANSI C引用的功能以及支持它的shell:
bash
, ksh
, zsh
ANSI C-quoted strings, which are enclosed in $'...'
, DO allow escaping embedded '
chars. ANSI C引用的字符串, 包含在
$'...'
,DO允许转义嵌入的'
字符。 as \\'
: 作为
\\'
:
alias foo=$'echo A \'*\' is born at $(date)'
Pitfalls : 陷阱 :
\\n
, \\t
, ... are interpreted, too (in fact, that's the purpose of the feature). \\n
, \\t
,...也被解释(事实上,这是该功能的目的)。 Use of alternating quoting styles , as in @Dropout's answer: 使用交替引用样式 ,如@ Dropout的答案:
Pitfall : 陷阱 :
'...'
and "..."
have different semantics , so substituting one for the other can have unintended side-effects: '...'
和"..."
具有不同的语义 ,因此将一个替换为另一个可能会产生意想不到的副作用:
alias foo="echo A '*' is born at $(date)" # DOES NOT WORK AS INTENDED
While syntactically correct, this will NOT work as intended, because the use of double quotes causes the shell to expand the command substitution $(date)
right away , and thus hardwires the date and time at the time of the alias definition into the alias . 虽然语法正确的,这将不会按预期进行,因为使用了双引号,shell会展开命令替换
$(date)
向右走 ,因而硬连线的别名定义成别名时的日期和时间 。
As stated: When defining an alias , you usually want single quotes around its definition so as to delay evaluation of the command until the alias is invoked . 如上所述:在定义别名时 ,通常需要围绕其定义使用单引号 ,以便延迟对命令的评估 ,直到调用别名为止。
Finally, a caveat : 最后,一个警告 :
The tricky thing in a Bourne-like shell environment is that embedding '
inside a single-quoted string sometimes - falsely - APPEARS to work (instead of generating a syntax error, as in the question), when it instead does something different: 在一个类似Bourne shell环境的棘手的事情是嵌入
'
单引号字符串中有时-错误-似乎工作 (而不是产生一个语法错误,因为在这个问题),当它反而就不一样了:
alias foo='echo a '*' is born at $(date)' # DOES NOT WORK AS EXPECTED.
This definition is accepted (no syntax error), but won't work as expected - the right-hand side of the definition is effectively parsed as 3 strings - 'echo a '
, *
, and ' is born at $(date)'
, which, due to how the shell parses string (merging adjacent strings, quote removal), results in the following, single , literal string: a * is born at $(date)
. 这个定义被接受 (没有语法错误),但不会按预期工作 - 定义的右侧被有效地解析为3个字符串 -
'echo a '
, *
和' is born at $(date)'
,由于shell解析字符串(合并相邻的字符串,引用删除),导致以下单个字面字符串: a * is born at $(date)
。 Since the *
is unquoted in the resulting alias definition, it will expand to a list of all file/directory names in the current directory (pathname expansion) when the alias is invoked. 由于
*
在生成的别名定义中未加引号 ,因此在调用别名时,它将扩展为当前目录(路径名扩展)中所有文件/目录名称的列表。
You chould use different quotes for surrounding the whole text and for inner strings. 你可以使用不同的引号来包围整个文本和内部字符串。
Try changing it to 尝试将其更改为
alias logspace="find /apps/ /opt/ -type f -size +100M -exec ls -lh {} \; | awk '{print $5, $9 }'"
In other words, your outer quotes should be different than the inner ones, so they don't mix. 换句话说,您的外部引号应该与内部引号不同,因此它们不会混合。
Community wiki update : 社区维基更新 :
'
) inside a string . '
)在字符串中 。 Note: Code snippets are meant to be pseudo code , not shell language. 注意:代码片段是伪代码 ,而不是shell语言。
Basic strings: You canNOT use the same quote within the string as the entire string is delimited with: 基本字符串:您不能在字符串中使用相同的引号,因为整个字符串是用以下分隔的:
foo='hello, 'world!'';
^--start string
^-- end string
^^^^^^^^--- unknown "garbage" causing syntax error.
You have to escape the internal strings: 你必须转义内部字符串:
foo='hello, \'world!\'';
^--escape
This is true of pretty much EVERY programming language on the planet. 这对于地球上几乎每种编程语言都是如此。 If they don't provide escaping mechanisms, such as
\\
, then you have to use alternate means, eg 如果它们不提供转义机制,例如
\\
,则必须使用其他方法,例如
quotechar=chr(39); // single quote is ascii #39
foo='hello ,' & quotechar & 'world!' & quotechar;
Escape the $
sign not the awk's single quotes and use double quotes for the alias. 转义
$
符号而不是awk的单引号,并使用双引号作为别名。
Try this : 试试这个 :
alias logspace="find /apps/ /opt/ -type f -size +100M -exec ls -lh {} \; | awk '{print \$5, \$9 }'"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.