我有以下命令:
ls /some/path/*dat | xargs -n 1 -I @ sh -c "echo `basename @`"
目录/some/path/
包含:
/some/path/a
/some/path/b
/some/path/c
/some/path/d
我想得到输出:
a
b
c
d
但我仍然得到完整路径。我究竟做错了什么 ?
编辑:顺便说一句,我知道有一个更简单的方法,我可以运行basname
而不是
echo `basename @`
但我需要运行一个复杂的命令,比如
octave --silent --eval "somefunction('`basename @`','@',...))"
编辑2:
这是实际的命令:
ls ~/phd/data/conll2012/dev.megam/*dat | xargs -P 16 -n 1 -I@ timeout -k 1s 15m sh -c "if [ ! -f '~/phd/xp/conll2012/dev.megam/@.$epsilon$mink$minn$alpha' ]; then octave --silent --eval \"xprp('~/phd/xp/conll2012/dev.megam/@.$epsilon$mink$minn$alpha.rp','@',$alpha,$mink,$minn,$epsilon);\" 2>> ~/xpgrid.log;fi"
基本上,我在一个目录中有一组文件,这个命令以这些文件为基础,将结果输出到另一个目录中,检查结果是否不存在。
因此,我需要具有完整路径的文件和仅具有基本名称的文件。
如何让它发挥作用?一开始的简单示例可以帮助您更清楚地理解这一点。
答案1
ls /some/path/*dat | xargs -n 1 -I @ sh -c 'echo `basename "@"`'
在您的代码中执行得basename
太早。
如果您不确定路径中没有空格或制表符,那么您应该使用(-d \\n
或find ... -print0 | xargs -0 ...
) 并注意."
@
答案2
只需将双引号更改为单引号即可修复测试用例,但您可能想了解 GNU parallel
。
你可以像这样做同样的事情:
parallel echo {/} ::: /some/path/*dat
(在某些 shell 中,您可能需要引用花括号。)
除了具有更清晰的语法之外,parallel
还将同时运行多个命令。
您的第二个示例如下所示:
parallel octave --silent --eval "\"somefunction('{/}', '{}', ...)\"" ::: /some/path/*dat
(引号内必须有引号,因为它会被评估两次。)
答案3
# find all my perl file names with *.pl or *.pm ext sorted
find src/ -name '*.pm' -o -name '*.pl' \
| xargs -n 1 -I @ sh -c 'echo `basename "@"`' | sort