2017-08-26 37 views
2

我想要做的就是如何在xargs中使用替換?

  1. 找到.txt擴展
  2. CP所有這些文件.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 

關於這一點,我有以下問題:

  1. 怎麼辦替代合適?
  2. 我很好奇xargs會做什麼並行的事情當for loop一個一個地做事情?

回答

1
  1. 怎麼辦替代合適?

你不能在你正在嘗試做的,因爲{}不是一個bash變量(只xargs的語法的一部分)的方式使用替代,因此慶典不能做就可以替換。

給它一個更好的辦法是創建一個完整的bash命令,並提供它作爲和參數xargs的(例如xargs -0 -i bash -c 'echo cp "$1" "${1%.txt}.dat"' - '{}' - 這種方式,您可以慶典替換)。

  1. 我很好奇xargs會在for循環做一件事情的時候平行嗎?

是,for循環會做認爲sequently但默認情況下xargs的總是會。但是,你可以使用的xargs-P選項並行化,從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 

SIGUSR1信號同時增加指令的數量 運行,或SIGUSR2減少的數量。您不能將其增加到實現定義的限制以上( 以--show-limits顯示)。你不能在 以下將它折起。xargs永遠不會終止它的命令;當被要求減少時,它只是等待多於一個現有的 命令在啓動另一個命令之前終止。

Please note that it is up to the called processes to properly manage parallel access to shared resources. For example, if 

其中超過一個嘗試打印到stdout, 的ouptut將在不確定的順序產生(而且很有可能混淆),除非流程,以防止一些這方面的 方式合作。使用某種鎖定方案是防止此類問題的一種方法。通常,使用鎖定方案將有助於確保正確的輸出,但會降低性能。如果您不想容忍性能差異,則只需安排每個進程生成一個單獨的輸出文件(或另外使用單獨的 資源)。

2

您可以使用:

find . -type f -name "*.txt" -print0 | 
xargs -0 -i bash -c 'echo cp "$1" "${1%.txt}.dat"' - '{}' 
0

如果你是不滿意的bash -c '...' -結構,你可以改用GNU並行:

find . -type f -name "*.txt" -print0 | parallel -0 cp {} {.}.dat 
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正在同時運行。