[英]Unix 'alias' fails with 'awk' command
我在Unix中创建了一个别名,发现以下命令失败了..
alias logspace='find /apps/ /opt/ -type f -size +100M -exec ls -lh {} \; | awk '{print $5, $9 }''
我得到以下内容:
awk: cmd. line:1: {print
awk: cmd. line:1: ^ unexpected newline or end of string
关于为什么管道awk命令失败的任何想法......
谢谢,肖恩。
补充@ Dropout的有用答案 :
问题是OP尝试使用'
内部 '
封闭(单引号)字符串。
在这种情况下, 最健壮的解决方案是替换每个内部 '
与'\\''
(原文如此):
alias logspace='find /apps/ /opt/ -type f -size +100M -exec ls -lh {} \; |
awk '\''{print $5, $9 }'\'''
'
(内单引号字符'...'
-enclosed)串在所有-即使不是逃避 。
"
双 -quoted字符串作为内部\\"
,并且,如@ Droput的回答,您可以直接嵌入'
字符。在那里,但请参阅下面的陷阱。) '
字符”。 - 在单引号字符串之外转义为\\'
- 拼接在一起 。 '\\''
表示:“关闭字符串”,“转单引号”,“启动新字符串”。 其他解决方案及其缺陷 :
以下讨论基于以下别名的替代解决方案:
alias foo='echo A '\''*'\'' is born at $(date)'
注意*
如何有效地用单引号括起来 - 使用上面的技术 - 以便在以后调用别名时防止路径名扩展。
当被调用时,这个别名打印文字 A * star is born
,然后是当时的日期和时间,例如: A * is born at Mon Jun 16 11:33:19 EDT 2014
。
使用名为ANSI C引用的功能以及支持它的shell: bash
, ksh
, zsh
ANSI C引用的字符串, 包含在$'...'
,DO允许转义嵌入的'
字符。 作为\\'
:
alias foo=$'echo A \'*\' is born at $(date)'
陷阱 :
\\n
, \\t
,...也被解释(事实上,这是该功能的目的)。 使用交替引用样式 ,如@ Dropout的答案:
陷阱 :
'...'
和"..."
具有不同的语义 ,因此将一个替换为另一个可能会产生意想不到的副作用:
alias foo="echo A '*' is born at $(date)" # DOES NOT WORK AS INTENDED
虽然语法正确的,这将不会按预期进行,因为使用了双引号,shell会展开命令替换$(date)
向右走 ,因而硬连线的别名定义成别名时的日期和时间 。
如上所述:在定义别名时 ,通常需要围绕其定义使用单引号 ,以便延迟对命令的评估 ,直到调用别名为止。
最后,一个警告 :
在一个类似Bourne shell环境的棘手的事情是嵌入'
单引号字符串中有时-错误-似乎工作 (而不是产生一个语法错误,因为在这个问题),当它反而就不一样了:
alias foo='echo a '*' is born at $(date)' # DOES NOT WORK AS EXPECTED.
这个定义被接受 (没有语法错误),但不会按预期工作 - 定义的右侧被有效地解析为3个字符串 - 'echo a '
, *
和' is born at $(date)'
,由于shell解析字符串(合并相邻的字符串,引用删除),导致以下单个字面字符串: a * is born at $(date)
。 由于*
在生成的别名定义中未加引号 ,因此在调用别名时,它将扩展为当前目录(路径名扩展)中所有文件/目录名称的列表。
你可以使用不同的引号来包围整个文本和内部字符串。
尝试将其更改为
alias logspace="find /apps/ /opt/ -type f -size +100M -exec ls -lh {} \; | awk '{print $5, $9 }'"
换句话说,您的外部引号应该与内部引号不同,因此它们不会混合。
社区维基更新 :
'
)在字符串中 。 注意:代码片段是伪代码 ,而不是shell语言。
基本字符串:您不能在字符串中使用相同的引号,因为整个字符串是用以下分隔的:
foo='hello, 'world!'';
^--start string
^-- end string
^^^^^^^^--- unknown "garbage" causing syntax error.
你必须转义内部字符串:
foo='hello, \'world!\'';
^--escape
这对于地球上几乎每种编程语言都是如此。 如果它们不提供转义机制,例如\\
,则必须使用其他方法,例如
quotechar=chr(39); // single quote is ascii #39
foo='hello ,' & quotechar & 'world!' & quotechar;
转义$
符号而不是awk的单引号,并使用双引号作为别名。
试试这个 :
alias logspace="find /apps/ /opt/ -type f -size +100M -exec ls -lh {} \; | awk '{print \$5, \$9 }'"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.