如何从终端使用默认程序打开多个文件?


13

我尝试使用打开一个文件夹中的所有.mp3文件,xdg-open 但发现它只打开一个!所以我搜索了一下,但是没有这样的问题!我发现“ evince”,但显然它会打开文本文件,而gnome-open也会打开一个文件。

我想从终端打开文件夹中相同格式的所有文件。我是Ubuntu的新手,所以请多解释一些。


1
xdg-open默认情况下应该真正能够做到这一点...只需将参数列表传递给程序即可。快来freedesktop.org上的人吧!:-)
西罗桑蒂利冠状病毒审查六四事件法轮功

Answers:


8

确实。您可以使用shell来解决此问题,如下所示:

ls -b *.mp3 | xargs -n 1 xdg-open

或者,如果您希望它更坚固,请尝试

find -iname '*.mp3' -print0 | xargs -0 -n 1 xdg-open

第一个不适用于名称中带有空格的文件,而第二个根本不起作用(find: paths must precede expression: -)。
Sparhawk

1
如果您仔细阅读,我会写“如果您希望它更健壮...”,因此第一个简单的版本确实不能用于空格,但这并不是故意的。第二种解决方案确实适用于ubuntu。仅供参考,find的较新版本默认将路径名设置为。
Agoston Horvath 2013年

我不确定第二个问题是缺少路径(尽管出现错误消息)。我尝试放入,.并得到了相同的错误消息。在另一个目录中,可以xdg-open: unexpected argument './foo.mp3'使用或不使用.
Sparhawk

另外,我认为,即使在“简单”的情况下,在名称中包含空格也不是一种罕见的情况,应该忽略它。
Sparhawk

我对您的特定设置还不够了解,不能肯定地说,但是xdg-open可以像我在新的ubuntu安装中描述的那样工作。如果不确定,请参见man xdg-open。
Agoston Horvath

4

你可以试试:

ls *.mp3 | while read -r file; do xdg-open "$file"; done

ls *.mp3将列出当前目录中的所有mp3文件,每个文件都在其单独的行中,并将输出通过管道传递到while循环中,读取每一行的内容,它将打开该内容(在这种情况下,这是mp3文件的名称) )在其默认应用程序中。


@karel我添加了-r标志。我认为这是正确解析名称中带有`\`的文件所必需的。
Sparhawk

2
嗯...不会打开同一程序的多个实例吗?
Braiam

@karel是的...我man read也根本没有列出任何标志!我的测试中没有出现错误,但这可能是因为我创建了aaaaa\a。在这种情况下,xdg-open只需尝试打开aaa两次,而不是aa\a。(好吧,这有点令人费解,但是我认为代码应该适用于所有情况。find为了避免lsand 的局限性,也许是一个更好的选择read。)此外,它如何造成严重的破坏?难道不只是要解析输出ls吗?
Sparhawk

@karel man read引用读取的C函数(该人的第2节)。这read是一个bash内置命令,因此您应该在man bash4632行中查找。@Sparhawk-感谢edititng。
RaduRădeanu2013年

@Braiam umm ... mp3并非如此,它取决于默认应用程序中的设置。行为与从Nautilus或您喜欢的文件管理器中打开多个文件时相同。
RaduRădeanu13年

4

我写了一个小脚本/usr/local/bin/o,尽管您可以调用它,/usr/local/bin/xdg-open并在需要时替换默认命令(假设您$PATH给它优先级)。另外,如果未提供任何参数,则此脚本将改为打开当前目录。

#!/usr/bin/env bash
if [ $# -eq 0 ]; then
  xdg-open . &> /dev/null
else
  for file in "$@"; do
    xdg-open "$file" &> /dev/null
  done
fi

如果您不希望不带任何参数打开当前目录,则保留默认行为,即显示用法。

#!/usr/bin/env bash
if [ $# -eq 0 ]; then
  xdg-open &> /dev/null
else
  for file in "$@"; do
    xdg-open "$file" &> /dev/null
  done
fi

注意,这与默认程序解析多个参数的能力无关,但是将为每个参数调用一次每个命令。我认为这不是一种优雅的方法,因为用户可能想要xdg-open不同类型的文件,并且某些命令无论如何都不会采用多个参数。


1

我写了这个bash脚本来涵盖我可能想到的所有使用情况:

#!/bin/bash
set -euo pipefail; shopt -s failglob # bash strict mode

max=${max:-10} # Set default maximum if $max is not set
[[ ${all:-} ]] && max=$# # Set max to all files if $all is non-null

for file in "${@:1:$max}"; do
  xdg-open "$file"
done &>>~/.xsession-errors

特征:

  • 将错误输出写入〜/ .xsession-errors,而不是污染终端或将其丢弃
  • 默认情况下最多打开10个文件(不超载屏幕/处理器)
  • 可以使用 max=20 open $(ls -Q)
  • 允许打开所有文件,例如 all=1 open $(ls -Q)

0

这里是单线:

ls -AQp | grep "\.mp3\"$" | xargs `xdg-mime query default audio/mpeg | grep -oP '.+(?=\.desktop)'`

当我安装了VLC时(这是mp3的默认设置),这将为我打开VLC目录中的所有mp3-文件。这不是任何一种“ 万能的解决所有在各种情况下都可以解决的情况 ”,但它应该可以工作。

说明:

ls -AQp列出“几乎所有”文件,引用文件名并在目录名称后添加斜杠。更换-p--file-type,如果你想排除符号链接为好。如果文件名中有空格,请报价。

grep "\.mp3\"$" 仅选择以“ .mp3”结尾的文件(加双引号)。

xargs 将整个程序重定向到以下subshel​​l返回的程序。

子壳:

xdg-mime query default audio/mpeg给出mime为的文件的默认应用程序名称,格式为“ app.desktop” audio/mpeg。您可以使用来检查环境中任何文件的mimetype xdg-mime query filetype /path/to/file。我得到了mp3文件的“音频/ mpeg”。

grep -oP '.+(?=\.desktop)' 从“ app.desktop”获取“ app”。

如果您打算在不会有太大变化的系统中非常频繁地使用它,则可能需要将其缩短为:

ls -AQp | grep "\.mp3\"$" | xargs default_app

在此处替换为default_app随文件打开的实际程序。您可以这样确定它的名称:

xdg-mime query default audio/mpeg | grep -oP '.+(?=\.desktop)'


xdg-open不会解决此问题,因为它在设计上仅接受一个参数。如果使用xargs -n1,则很可能会碰壁,导致所涉及的应用程序可能会在新实例中打开每个文件,这可能会以多种方式造成丑陋。


-1

您可以使用这些命令

cd /path/to/source_folder

find . -type f -name *.mp3 -exec vlc {} \+

仅当您的音乐播放器支持多个文件作为命令行参数时。vlc用您选择的音乐播放器替换。

在我的测试中,这可与RhythmBox和VLC一起使用。


find...... -exec对每个文件运行单独的命令?而且,如果您的音乐播放器支持多个文件作为命令行参数,则可以使用vlc *.mp3
Sparhawk

@Sparhawk没有\+结尾
AB

@AB是的,很好。我错了。但是,按照我的第二句话,无论如何find都要硬编码似乎毫无意义vlc。(问题表明它们都在一个目录中。)
Sparhawk

仅仅+就足够了,没有必要\+
Grumbel

-1

如果要在VLC中打开文件,请对mp3文件使用此命令。

vlc /directory/*.mp3

注意:用于cvlc不带界面的VLC。


3
问题是“默认程序”,因此直接使用VLC有点...没有意义。
大师
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.