Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 优化xargs参数枚举_Linux_Bash_Xargs - Fatal编程技术网

Linux 优化xargs参数枚举

Linux 优化xargs参数枚举,linux,bash,xargs,Linux,Bash,Xargs,xargs参数枚举的这种用法能否得到更好的优化? 目的是在实际命令的中间注入单个参数。 我有: 或 我得到: line 1 here line 2 here line 3 here 这正是我所需要的,但我想知道是否可以避免循环和临时变量?也许是这样 echo {1..3} | tr " " "\n" | xargs -n1 sh -c ' echo "line $0 here"' tr用换行符替换空格,因此xargs可以看到三行。如果有更好(更有效)的解决方案,我不会感到惊讶,但这是一个非常

xargs参数枚举的这种用法能否得到更好的优化? 目的是在实际命令的中间注入单个参数。

我有:

我得到:

line 1 here
line 2 here
line 3 here
这正是我所需要的,但我想知道是否可以避免循环和临时变量?

也许是这样

echo {1..3} | tr " " "\n" | xargs -n1 sh -c ' echo "line $0 here"'
tr
用换行符替换空格,因此
xargs
可以看到三行。如果有更好(更有效)的解决方案,我不会感到惊讶,但这是一个非常简单的解决方案


请注意,我已修改了先前的回答,以删除注释中建议的
{}
的使用,以消除潜在的代码注入漏洞。

您需要通过换行符分隔
xargs
的输入:

echo {1..3}$'\n' | xargs -I% echo line % here
对于阵列扩展,可以使用
printf

ar=({1..3})
printf '%s\n' "${ar[@]}" | xargs -I% echo line % here
(如果它只是用于输出,您可以不使用
xargs

printf 'line %s here\n' "${ar[@]}"

)GNU sed有一个不为人所知的特性。您可以将
e
标志添加到
s
命令中,然后sed执行模式空间中的任何内容,并使用输出替换模式空间(如果该命令有效)

如果您真的只对echo命令的输出感兴趣,您可以尝试这个GNU-sed示例,它消除了临时变量、循环(以及xargs):

  • 它获取一个令牌(即由空格分隔的任何令牌)
  • 将其替换为
    echo“line\1 here”\n
    命令,将
    \1
    替换为标记
  • 然后执行echo
  • 将echo命令的输出放回模式空间
  • 这意味着它会输出三次回声的结果

但获得所需输出的更好方法是跳过执行,直接在sed中进行转换,如下所示:

echo {1..3} | sed -r 's/([^ ])+ ?/line \1 here\n/g' 

尝试不使用
xargs
。在大多数情况下,
xargs
是过度杀伤力。 根据您真正想要的,您可以选择以下解决方案

# Normally you want to avoid for and use while, but here you want the things splitted.
for i in $(echo {1 2 3} );do 
   echo line $i here;
done

# When you want 1 line turned into three, `tr` can help
echo {1..3} | tr " " "\n" | sed 's/.*/line & here/'

# printf will repeat itself when there are parameters left
printf "line %s here\n" $(echo {1..3})

# Using the printf feature you can avoid the echo
printf "line %s here\n"  {1..3}

{1..3}中i的
;在这里做回音行$i;完成
?您的问题确实不清楚,看起来像XY问题。您考虑的具体用例是什么?很可能有比您要求的更好的设计。@gniourf_gniourf-只是寻找一种简洁的参数使用方式,在后续命令中的任何地方通过管道,这不是真正的特定用例。对我来说,这从一开始看起来就像一个破碎的设计。如果您没有在shell脚本方面做过实验,那么您会忽略很多警告(大多数警告都来自于您显然在混合代码和数据这一事实)。从现在开始,,一种可能的情况是,您错误地学习了一些糟糕的技术,这些技术会比您预期的更快地对您造成负面影响。@gniourf_gniourf-谢谢您的宝贵评论。您介意给我指一个资源,在shell脚本编写的环境中,我可以学习代码和数据的适当分离吗?我不知道这个括号扩展处理前缀和后缀。很高兴知道。可能值得一提的是,这在涉及其他类型扩展的其他场景中不起作用(例如,扩展数组中的所有元素)。请注意,
echo{1..3}$'\n'
扩展为
echo 1$'\n'2$'\n'3$'\n'
,因此
echo
可以看到三个参数。现在,
echo
打印由空格分隔的参数,因此,
2
3
将以空格作为前缀,并且您还将得到一个空的尾随行(因为
echo
还将在末尾添加一个新行)。如果以后您想更可靠地使用(GNU)
xargs
-d\\n
,这将导致问题。
printf
版本显然更高级,更惯用。更惯用的方法是使用
printf'%s\n'{1..3}
。非常正确。我不会更新我的答案,另一个答案已经更好、更完整了,而我的答案虽然不是最好的,但也没有错。请注意,在
sh
代码中使用
{}
是一件非常糟糕的事情:您将代码与数据混为一谈!(这是问题的主要来源之一,也是一种可怕的反模式,您应该认识到并消除它)。事实上,伪造将产生任意代码执行的数据非常容易,例如,
printf“%s\n”one;rm-rf一些珍贵的目录"| xargs-I{}sh-c'回音线{}这里;',你会得到一些惊喜!必须将数据作为数据处理。为此:
。|xargs-n1 sh-c“echo”行$1在此“'sh
。同样的错误通常出现在
find
-exec sh-c'。。。{} ...' \;
@gniourf\u gniourf我想修改我的答案来纠正这个问题,但我无法获得您建议xargs使用“printf”或基于“tr”的解决方案的代码($1扩展为零),我得到的只是“line here”。有什么我做错了吗?@gniourf\u gniourf实际上,如果我用$0替换$1,它会起作用。可以吗?
echo {1..3} | sed -r 's/([^ ])+/echo "line \1 here"\n/ge
echo {1..3} | sed -r 's/([^ ])+ ?/line \1 here\n/g' 
# Normally you want to avoid for and use while, but here you want the things splitted.
for i in $(echo {1 2 3} );do 
   echo line $i here;
done

# When you want 1 line turned into three, `tr` can help
echo {1..3} | tr " " "\n" | sed 's/.*/line & here/'

# printf will repeat itself when there are parameters left
printf "line %s here\n" $(echo {1..3})

# Using the printf feature you can avoid the echo
printf "line %s here\n"  {1..3}