awk 与 xargs 中的其他命令结合使用的正确语法 sh –c

Eka*_*ina 5 shell xargs awk quoting

如何使此命令工作:

ls * | xargs -I {} sh -c 'echo {}; awk '{print $1}' {} | uniq'
Run Code Online (Sandbox Code Playgroud)

它应该做的很简单:uniq在第一列中为文件夹中的每个文件打印其名称和值

它不起作用,因为该$符号被识别为字符串符号的结尾,我猜应该与引号有关。

错误信息:

awk: cmd. line:1: {print
awk: cmd. line:1:       ^ unexpected newline or end of string
Run Code Online (Sandbox Code Playgroud)

Gil*_*il' 8

第二个单引号终止第一个单引号字符串'echo {}; awk '。然后{print $1}是不带引号的,然后是另一个单引号的 string ' {} | uniq'。这在任何带有语法突出显示的编辑器中都应该很清楚;如果您查看问题中突出显示的语法,也很清楚。

这里最简单的方法是完全避免嵌套引用。将 awk 脚本作为参数传递给sh.

xargs -I {} sh -c 'echo "$1"; awk "$0"' '{print $1}' {} | uniq'
Run Code Online (Sandbox Code Playgroud)

(我还用{}相应的参数替换了脚本中的sh。永远不要{}在脚本中使用:它会被解析为 shell 语法,而不是文件名,所以它会在任何包含 shell 特殊字符的文件名上失败。)

要在单引号文字中有效地包含单引号,请使用'\''(正式地结束单引号文字,然后添加一个单引号,由于前面的反闪而按字面解释,然后开始另一个单引号文字;但效果是一样的)。

xargs -I {} sh -c 'echo {}; awk '\''{print $1}'\'' {} | uniq'
Run Code Online (Sandbox Code Playgroud)

或者,在一个级别使用单引号,在另一级别使用双引号,但这会变得更加棘手。

(我假设您的无意义命令ls *只是一个极其简化的示例。)