有没有办法在管道上使用xargs?


15

我正在尝试自动将移动到一个文件夹的flac文件转换为另一个文件夹中的mp3。

我当前的代码行是这样的:

inotifywait -m -r -q -e moved_to --format "'%w%f'" ~/test |  xargs -I x flac -cd x - | lame -b 320 - /media/1tb/x.mp3

为了解释到目前为止的工作方式,inotifywait递归地监视〜/ test到那里移动的文件,并将路径和文件名输出到管道。xargs使用该名称并创建正确的flac命令,将x替换为文件名并将文件解码到另一个管道。在新管道中,lame将flac的输出处理到/ media下的mp3中。我希望xargs以某种方式到达整个管道,在lame命令中替换x或以某种方式将其发送到两个命令都可以访问的变量。我试图弄乱命名管道和爵士乐,但是在两个命令之间通过管道传输实际数据这一事实使我费解了。

Answers:


16

如果我理解正确,则希望flac … | lame …为每个输入行启动一个实例,并将输入插值到两个命令的参数中。

由于需要xargs启动管道,因此需要使其启动一个能够创建管道的程序,即外壳程序。

inotifywait -m -r -q -e moved_to --format "%w%f" ~/test |
xargs -l sh -c 'flac -cd "$0" - | lame -b 320 - "/media/1tb/$0.mp3"'

或者,让调用shell逐行读取一行并运行管道。

inotifywait -m -r -q -e moved_to --format "%w%f" ~/test |
while IFS= read -r file; do
  flac -cd "$file" - | lame -b 320 - "/media/1tb/$file.mp3"
done

请注意,格式%w%f会产生一个绝对路径,您要在该绝对路径之前/media/1tb和之后添加.mp3。如果要删除lame命令中文件的目录部分,请更改$file${file##*/}。如果要剥离扩展名,请更改$file${file%.*}。如果您想两者都做,则必须分两个步骤进行。如果要在其下重现目录层次结构/media/1tb,可以使用mkdir -p

cd ~/test
inotifywait -m -r -q -e moved_to --format "%w%f" . |
while IFS= read -r file; do
  [ -f "$file" ] || continue; # skip directories and other special files
  dir=${file%/*}; file=${file##*/}
  mkdir -p "/media/1tb/$dir"
  flac -cd "$dir/$file" - | lame -b 320 - "/media/1tb/$dir/${file#.*}.mp3"
done

3

您可以尝试类似:

inotifywait -m -r -q -e moved_to --format "'%w%f'" ~/test \
    | while read x; do \
        flac -cd "$x" - | lame -b 320 - "/media/1tb/$x.mp3"
    done;

1
while read …是一个解决方案,但然后放下xargs。您写的内容没有任何意义:您认为xargs从何处获得输入?而且您应该正确地引用事物,音乐文件名通常包含空格。
吉尔(Gilles)“所以,别再邪恶了”

@Gilles尚不清楚/我不清楚OP在做什么,这就是为什么我说“您可以尝试类似 ”和“我不确定xargs位是否符合您的意图”之类的原因我认为,这不是最佳答案,而是正确方向的暗示。已解决引用问题并删除了xargs。
goldilocks 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.