我在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命令失败的任何想法......
谢谢, 肖恩。
答案 0 :(得分:39)
问题在于OP尝试在{/ 1}} '
- 附带(单引号)字符串中使用'
。
在这种情况下,最强大的解决方案是用'
替换每个内部 '\''
(原文如此) :
alias logspace='find /apps/ /opt/ -type f -size +100M -exec ls -lh {} \; |
awk '\''{print $5, $9 }'\'''
'
- 封闭的)字符串中使用'...'
个字符串 - 甚至不用转义 。
"
转义为\"
,并且,如@ Droput的答案,您可以直接,嵌入'
字符,但请看下面的陷阱。)'
字符。 - 转义在外单引号字符串\'
- 拼接在 。'\''
意味着:"关闭字符串","转单引号","开始新的字符串" 其他解决方案及其陷阱:
以下根据以下别名讨论替代解决方案:
alias foo='echo A '\''*'\'' is born at $(date)'
注意*
如何有效地用单引号括起来 - 使用上述技术 - 以便在以后调用别名时防止路径名扩展。
调用时,此别名会打印 literal A * star is born
,然后是然后 - 当前日期和时间,例如:A * is born at Mon Jun 16 11:33:19 EDT 2014
。
使用名为ANSI C quoting的功能,其中包含支持它的外壳: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
虽然语法正确,但这不会按预期工作,因为使用 double 引号会导致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解析字符串的方式(合并相邻的字符串,引用删除),会产生以下结果, single ,文字字符串:a * is born at $(date)
。由于结果别名定义中*
未加引号,因此在调用别名时,它将扩展为当前目录(路径名扩展)中所有文件/目录名称的列表。
答案 1 :(得分:4)
你可以使用不同的引号来包围整个文本和内部字符串。
尝试将其更改为
alias logspace="find /apps/ /opt/ -type f -size +100M -exec ls -lh {} \; | awk '{print $5, $9 }'"
换句话说,您的外部引号应该与内部引号不同,因此它们不会混合。
答案 2 :(得分:2)
社区维基更新:
'
) in 字符串即可。注意:代码段应该是伪代码,而不是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;
答案 3 :(得分:1)
转义$
而不是awk的单引号,并使用双引号作为别名。
尝试一下:
alias logspace="find /apps/ /opt/ -type f -size +100M -exec ls -lh {} \; | awk '{print \$5, \$9 }'"