我想做的是
.txt
分机号.dat
档案它可以这样做:
for f in `find . -type f -name "*.txt"`; do cp $f ${f%.txt}.dat; done
我想用xargs做这个,我试过这个:
find . -type f -name "*.txt" | xargs -i cp {} ${{}%.txt}.dat
我这样做的错误:
bad substitution
关于这一点,我有这些问题:
xargs
for loop
在=
逐一做事时会做些事情吗? 答案 0 :(得分:2)
您可以使用:
find . -type f -name "*.txt" -print0 |
xargs -0 -i bash -c 'echo cp "$1" "${1%.txt}.dat"' - '{}'
答案 1 :(得分:2)
- 如何正确地进行替换?
醇>
你不能以你想要的方式使用替换,因为{}
不是bash变量(只是xargs语法的一部分),因此bash不能对它进行替换。
更好的方法是创建一个完整的bash命令,并将其作为参数提供给xargs(例如xargs -0 -i bash -c 'echo cp "$1" "${1%.txt}.dat"' - '{}'
- 这样你可以进行bash替换。)
- 我很好奇,当for循环做一个接一个的事情时,xargs会做并行的事情吗?
醇>
是的,for
循环会做后续的思考,但默认情况下xargs会一直这样做。但是,您可以使用-P
的{{1}}选项对其进行并行化,来自xargs
手册页:
xargs
SIGUSR1信号增加命令数 同时运行,或SIGUSR2减少数量。您不能将其增加到实现定义的限制之上(即 显示--show-limits)。你不能 将它折痕低于1. xargs永远不会终止它的命令;当被要求减少时,它只是等待不止一个存在 命令在开始另一个之前终止。
-P max-procs, --max-procs=max-procs Run up to max-procs processes at a time; the default is 1. If max-procs is 0, xargs will run as many processes as possible at a time. Use the -n option or the -L option with -P; otherwise chances are that only one exec will be done. While xargs is running, you can send its process a
不止一个人试图打印到stdout, 除非过程在某些过程中协作,否则将以不确定的顺序生成ouptut(并且非常可能混淆) 防止这种情况的方法。使用某种锁定 方案是防止此类问题的一种方法。通常,使用锁定方案将有助于确保正确的输出 降低性能。如果你不想忍受 性能差异,只需安排每个进程生成一个单独的输出文件(或以其他方式单独使用 资源)。
答案 2 :(得分:0)
如果您对bash -c '...' -
构造不满意,可以使用GNU Parallel:
find . -type f -name "*.txt" -print0 | parallel -0 cp {} {.}.dat
答案 3 :(得分:0)
xargs
和其他工具不如 Perl 灵活。
~ ❱ find . | perl -lne '-f && ($old=$_) && s/\.txt/.dat/g && print "$old => $_"'
./dir/00.file.txt => ./dir/00.file.dat
./dir/06.file.txt => ./dir/06.file.dat
./dir/05.file.txt => ./dir/05.file.dat
./dir/02.file.txt => ./dir/02.file.dat
./dir/08.file.txt => ./dir/08.file.dat
./dir/07.file.txt => ./dir/07.file.dat
./dir/01.file.txt => ./dir/01.file.dat
./dir/04.file.txt => ./dir/04.file.dat
./dir/03.file.txt => ./dir/03.file.dat
./dir/09.file.txt => ./dir/09.file.dat
然后代替print
函数使用:rename $old, $_
使用此单行,您可以重命名任何您喜欢的内容
要强制xargs
使用并行模式,您应该使用-P
,如:
ls *.mp4 | xargs -I xxx -P 0 ffmpeg -i xxx xxx.mp3
并行将所有.mp4
个文件转换为.mp3
。因此,如果您有10 mp4
,那么10 ffmpeg
同时运行。