➜ ~ cat .zshrc | grep xclip
alias c="xclip -selection c"
alias -g v='"$(xclip -selection c -o)"'
➜ ~ v
zsh: 没有那个文件或目录: file:///home/roach/Downloads/pure.png
➜ ~
中文“没有那个文件或目录”的意思是“没有文件或目录”。
我想复制位于 的文件/home/roach/Downloads/pure.png
。当我在dolphin KDE中选择它并复制(单击鼠标右键,然后单击复制)后,有没有办法得到/home/roach/Downloads/pure.png
而不是file:///home/roach/Downloads/pure.png
上面显示的?
我认为是使用sed
删除多余file://
字符之类的命令,但没有得到正确的方法。
➜ ~ alias -g v='"$(xclip -selection c -o)|sed -e 's/file:\/\///'"'
➜ ~ v
zsh: 没有那个文件或目录: file:///home/roach/Downloads/pure.png|sed -e s/file:////
➜ ~
那么,如何纠正我的alias -g v
呢?
答案1
shell 本身可以执行此替换,从而避免外部程序的更昂贵的 fork 和 exec。详细内容请参见“参数扩展” zshexpn(1)
。
% x=file:///etc/passswd; print ${x#file://}
/etc/passswd
所以在你的情况下也许是这样的
% alias -g v='${$(xclip -selection c -o)#file://}'
% print -l v
/etc/passswd
请注意,这v
是一个有点常见的字母,因此可能不适合作为全局别名。
您可能还想决定如何处理名称中带有空格的内容;将print -l
揭示以下之间的区别:
alias -g v='${$(xclip -selection c -o)#file://}'
alias -g v='${"$(xclip -selection c -o)"#file://}'
当剪贴板的内容中有空格时。
答案2
如您所知,别名
alias -g v='"$(xclip -selection c -o)"'
意味着,当您调用 时v
,shell 会尝试执行名为剪贴板内容的命令。这就是您的第一个代码片段中发生的情况。然而,调用v
和观察其效果会产生误导,因为其预期用途全球的别名是其他命令的参数。
如果您正确使用命令替换 ( ) 并引用,您的sed
基于 - 的解决方案将起作用:$(...)
alias -g v='$(xclip -selection clipboard -o | sed '"'"'s|^file://||'"'"')'
在这里,xclip
将剪贴板的内容通过管道传输到sed
,这会删除file://
其开头的部分(模式已锚定,请注意^
)。避免在脚本中使用命令分隔/
符使其更具可读性,并且无需在模式中转义。 命令替换意味着管道的输出在被调用的地方被替换。s
sed
/
v
然后您可以将其用作:
cp -- v /path/to/destination
请注意,这将使对当前工作目录中命名的文件进行操作变得更加困难v
,因为文字v
将始终被替换。作为解决方法,您将能够使用相对路径./v
。
(另外,请考虑某些程序接受无前缀的单字母选项,例如完全合法(但非 POSIX)ps v
。单字母全局别名是不安全的)。
最后但并非最不重要的一点是,这样的全局别名不适用于名称包含空格字符的文件,因为在替换别名后它们将被 shell 分割。
或者,您可以避免使用全局别名并定义:
alias v="xclip -selection clipboard -o | sed 's|^file://||'"
可以用作:
cp -- "$(v)" /path/to/destination
这也适用于带有空格字符的文件名。
但请注意:
- 利用 shell 的替换功能,如中所述特里格的回答,效率会更高。
Dolphin 显示并复制到剪贴板的文件名是经过编码的,因此只要包含不常见的字符,就不适合由 shell 使用。例如:
touch $'file with a\nnewline' # Copied in Dolphin % echo "$(v)" file with a%0Anewline % cat "$(v)" cat: '/path/to/file with a%0Anewline': No such file or directory