例如:
find /usr/lib -maxdepth 1 -type l -iname "*libblas*"|xargs -I{} echo "{} =>" $(realpath {})
我想输出:
/usr/lib/libblas.so.3gf=>/usr/lib/libblas/libblas.so.3gf.0
/usr/lib/libblas.so=>/usr/lib/libblas/libblas.so.3gf.0
/usr/lib/libblas.a=>/usr/lib/libblas/libblas.a
这不起作用,因为$()
中的值在脚本实际运行之前展开。
有什么办法可以达到这个效果吗?在bash中没有循环?
答案 0 :(得分:4)
可替换地:
find /usr/lib -maxdepth 1 -type l \
-exec echo -n '{} =>' \; \
-exec realpath '{}' \;
答案 1 :(得分:1)
让xargs调用shell:
find /usr/lib -maxdepth 1 -type l -iname "*libblas*"|xargs -I{} sh -c 'echo "{} =>" $(realpath {})'
答案 2 :(得分:1)
您需要在知道文件名后进行命令替换。所以你需要xargs
来调用shell并在那里进行替换。
由于您一次在单个文件上运行命令,因此使用xargs
是一种无用的复杂功能(并且它还会破坏某些文件名)。使用-exec
!
find /usr/lib -maxdepth 1 -type l -iname "*libblas*" -exec sh -c 'echo "$0 => $(realpath "$0")' {} \;
通过不使用命令替换,您可以使这一点稍快一点,而不是更清晰:
find /usr/lib -maxdepth 1 -type l -iname "*libblas*" -exec sh -c 'echo -n "$0 => "; realpath "$0"' {} \;
为了让事情变得更快,不要为每个文件调用新的shell进程:
find /usr/lib -maxdepth 1 -type l -iname "*libblas*" -exec sh -c 'for x; do echo -n "$x => "; realpath "$x"; done' _ {} +
(您可以对xargs
执行相同操作,但只需删除xargs
并坚持使用更简单,更快速,更强大的-exec
。)
答案 3 :(得分:0)
尝试逐行转换每个文件名"而"循环:
find ... | while read f; do echo "$f" '=>' "$(realpath $f)" ; done
答案 4 :(得分:0)
最短的似乎是使用GNU Parallel:
find /usr/lib -maxdepth 1 -type l -iname "*libblas*"|parallel echo {} '=\> $(readlink -f {})'