如何转义 perl 中的 < <() 习语

how to escape the < <() idiom in perl

我有一个系统命令正在尝试执行,但它给我错误 "Syntax error: redirection unexpected"

尝试命令:

datamash -ft, -g 1 mean 3 mean 4 < <(tail -n +2 yourfile | sort -t, -k1,2) | cut -d, -f1,2,5,6 

我尝试了 readpipe 并且还用 \< \< 转义了 < <,但是没有用。

下面的命令不起作用 ==>

`datamash -ft, -g 1 mean 3 mean 4 \< \<(tail -n +2 yourfile | sort -t, -k1,2) | cut -d, -f1,2,5,6`

反引号又名 readpipe 期望命令传递给 sh(或 Windows 中的 cmd)。 您似乎有 bash 命令而不是 sh 命令。固定:

`bash -c 'datamash -ft, -g 1 mean 3 mean 4 < <(tail -n +2 yourfile | sort -t, -k1,2) | cut -d, -f1,2,5,6'`

如果你有变量要插值,它看起来像

use String::ShellQuote ( shell_quote );

my $qfn = '...';
my $tail_cmd = shell_quote('tail', '-n', '+2', $qfn);
my $bash_cmd = "datamash -ft, -g 1 mean 3 mean 4 < <( $tail_cmd | sort -t, -k1,2 ) | cut -d, -f1,2,5,6";
my $sh_cmd = shell_quote('bash', '-c', $bash_cmd);
`$sh_cmd`

正如@chepner 所注意到的,bash 命令可以转换为与 sh 兼容的更简单的命令。这将第一个片段缩减为以下内容:

`tail -n +2 yourfile | sort -t, -k1,2 | datamash -ft, -g 1 mean 3 mean 4 | cut -d, -f1,2,5,6'`

这并不能帮助我们避免在第二个片段中使用 shell_quote,但它确实减少了以下内容:

use String::ShellQuote ( shell_quote );

my $qfn = '...';
my $tail_cmd = shell_quote('tail', '-n', '+2', $qfn);
my $sh_cmd = "$tail_cmd | sort -t, -k1,2 | datamash -ft, -g 1 mean 3 mean 4 | cut -d, -f1,2,5,6";
`$sh_cmd`

我什至懒得在这里使用进程替换。使用普通管道即可:

`tail -n +2 yourfile | sort -t, -k1,2 | datamash -ft, -g 1 mean 3 mean | cut -d, -f1,2,5,6`

当一个命令(如 datamash)需要在当前 shell 中 运行,或者当你想将一个命令的输出提供给另一个时,进程替换是最有用的命令只从一个命名文件中读取,而不是它的标准输入。这两种情况都不适用于此处。