我有一个源输入,input.txt
a.txt
b.txt
c.txt
Run Code Online (Sandbox Code Playgroud)
我想将这些输入提供给程序,如下所示:
my-program --file=a.txt --file=b.txt --file=c.txt
Run Code Online (Sandbox Code Playgroud)
所以我尝试使用xargs,但没有运气.
cat input.txt | xargs -i echo "my-program --file"{}
Run Code Online (Sandbox Code Playgroud)
它给
my-program --file=a.txt
my-program --file=b.txt
my-program --file=c.txt
Run Code Online (Sandbox Code Playgroud)
但我想要
my-program --file=a.txt --file=b.txt --file=c.txt
Run Code Online (Sandbox Code Playgroud)
任何的想法?
我一直试图使用GNU并行一段时间,但我从来没有能够让它完全运行!
例如,运行(在非空目录中!):
ls | parallel echo # Outputs single new line
ls | parallel echo echo echo # Outputs three new lines.
ls | parallel echo {} # /bin/bash: {}: command not found
ls | parallel echo '{}' # /bin/bash: {}: command not found
ls | parallel 'echo {}' # Outputs: {}
ls | parallel -IMM 'echo MM' # Outputs: MM
Run Code Online (Sandbox Code Playgroud)
它似乎只是将每个参数作为命令执行,这没有任何意义.
我试过bash,zsh,tcsh,csh和sh,但无济于事.
我的源代码树包含几个使用Git源代码控制的目录,我需要对整个树进行tarball,不包括对Git元数据或自定义日志文件的任何引用.
我以为我会使用find/egrep/xargs/tar的组合,但不知何故tar文件包含.git目录和*.log文件.
这就是我所拥有的:
find -type f . | egrep -v '\.git|\.log' | xargs tar rvf ~/app.tar
Run Code Online (Sandbox Code Playgroud)
有人能在这里解释我的误会吗?为什么tar处理find和egrep正在过滤的文件?
我也对其他技术持开放态度.
当我xargs有时使用时,我不需要显式使用替换字符串:
find . -name "*.txt" | xargs rm -rf
Run Code Online (Sandbox Code Playgroud)
在其他情况下,我想指定替换字符串,以便执行以下操作:
find . -name "*.txt" | xargs -I '{}' mv '{}' /foo/'{}'.bar
Run Code Online (Sandbox Code Playgroud)
上一个命令会将当前目录下的所有文本文件移入/foo,并将扩展名附加bar到所有文件.
如果不是将一些文本附加到替换字符串,我想修改该字符串,以便我可以在文件的名称和扩展名之间插入一些文本,我该怎么做?例如,假设我想要像上一个示例中那样做,但是文件应该重命名/移动<name>.txt到/foo/<name>.bar.txt(而不是/foo/<name>.txt.bar).
更新:我设法找到一个解决方案:
find . -name "*.txt" | xargs -I{} \
sh -c 'base=$(basename $1) ; name=${base%.*} ; ext=${base##*.} ; \
mv "$1" "foo/${name}.bar.${ext}"' -- {}
Run Code Online (Sandbox Code Playgroud)
但我想知道是否有更短/更好的解决方案.
我经常想写这样的命令(zsh如果它是相关的):
find <somebasedirectory> | \
grep stringinfilenamesIwant | \
grep -v stringinfilesnamesIdont | \
xargs dosomecommand
Run Code Online (Sandbox Code Playgroud)
(或更复杂的greps组合)
近年来find添加了-print0交换机,并添加了xargs -0,它允许通过空终止文件名来优雅地处理名称中带有空格的文件,从而允许:
find <somebasedirectory> -print0 | xargs -0 dosomecommand
Run Code Online (Sandbox Code Playgroud)
但是,grep(至少我拥有的版本,Ubuntu上的GNU grep 2.10),似乎没有等效消耗并生成以null结尾的行; 它有--null,但这似乎只与使用-lgrep直接搜索文件时输出名称有关.
我可以使用与grep相同的选项或选项组合吗?或者,是否有一种简单而优雅的方式来表达我的命令管道,只需使用find -regex或Perl?
我有以下命令:
find . -type d -mtime 0 -exec mv {} /path/to/target-dir \;
Run Code Online (Sandbox Code Playgroud)
这会将创建的目录移动到另一个目录.如何使用xargs而不是exec做同样的事情.
我有一个pages.txt包含100个URL 的文件.我想逐一检查它们并在第一个问题上失败.这就是我正在做的事情:
cat pages.txt | xargs -n 1 curl --silent \
--output /dev/null --write-out '%{url_effective}: %{http_code}\n'; echo $?
Run Code Online (Sandbox Code Playgroud)
退出代码是1,但我只在整个文件完成时看到它.如何提前停止,关于第一个问题?
我想获得我的应用程序中的行数.我正在使用此代码:
find . "(" -name "*.m" -or -name "*.h" ")" -print | xargs wc -l
Run Code Online (Sandbox Code Playgroud)
它在其他应用程序中运行良好,但对于我的一个应用程序,它给出错误"xargs unterminated quote".
我对此非常困惑.需要一些澄清.
例1:
pgrep string | xargs ps
Run Code Online (Sandbox Code Playgroud)
例2:
find . | xargs grep whatever
Run Code Online (Sandbox Code Playgroud)
从例1开始,我就是这样收集的:
搜索一个"字符串",它是正在运行的进程名称的一部分,并将所有匹配的进程ID返回给'xargs ps' - >,它只是将ps附加到匹配项(它们是process-id本身)以获得相同的输出为:
ps <processid>
Run Code Online (Sandbox Code Playgroud)
有人能解释一下xargs在这种情况下的真正作用吗?
从例2开始,我就是这样收集的:
它是从当前工作目录中递归搜索一些"字符串".在这里,'xargs'究竟是如何工作的?
我认为'xargs'反复将标准输入的数据附加到给予xargs(通常是UNIX命令本身)的'参数'.
来自xargs()手册页:
xargs从标准输入中读取项目,由空格分隔(可以使用双引号或单引号或反斜杠保护)或换行符,并使用任何初始参数执行命令(默认为/ bin/echo)一次或多次从标准输入读取的项目.标准输入上的空行将被忽略.
在POSIX定义的xargs命令通吃它从标准输入接收物品并将它们作为命令行参数来接收它自己的命令行命令.例如:grep -rn "String" | xargs rm.
什么是PowerShell中的等价物?
以下问题都是这样问的:
但没有正确的答案,因为所有的答案要么使用ForEach-Object,它会一次一个地处理项目(比如xargs -n1),它会得到所给出的例子的预期结果,或者将中间结果存储在变量中,这会冒犯我的功能命令行福.