我正在使用 Ubuntu 14.04,但我猜这个东西在几乎所有版本的 Ubuntu 中都可以看到。
当我使用 nautilus 复制文件Ctrlc并粘贴到 gedit 中时,它会粘贴如下文本,/home/urvish/.bash_history
这对我来说很完美。但是当我使用 将其粘贴到终端中时,CtrlShiftv它显示如下file:///home/urvish/.bash_history
。
有什么方法可以file://
在粘贴时删除前面的内容?(我知道我可以手动完成,但我经常这样做,而且总是手动执行很耗时)。
答案1
gnome-terminal 的作用
通过阅读 Gtk 文档,似乎程序可以通过两种方式处理剪贴板内容 - 纯文本和文件 URI 列表。无论出于何种原因,gnome-terminal
决定区分两者是个好主意,因此当您将文件从 Nautilus 复制到时gnome-terminal
,终端会检索 URI 列表,而其他程序 - 仅检索纯文本。
自动编辑剪贴板会稍微麻烦一些(尽管我仍在追求这个想法) - 我们需要定义一种方法来检测您尝试粘贴剪贴板内容的位置,并且运行将脚本编辑为纯文本的持久脚本(有效地删除 URI)将阻止您将文件从一个 Nautilus 窗口复制到另一个窗口。
拖放可能是最简单的解决方案。但由于要求使用脚本方法,我想到了两种手动方法。一种依赖于 Nautilus 的内置功能,即向右键菜单添加脚本。另一种依赖于输入特定的快捷方式前粘贴到 gnome-terminal。
手动脚本方法,版本 1
该脚本将被放入文件夹中,并通过右键单击文件并编辑属性中的权限选项卡~/.local/share/nautilus/scripts
使其可执行。实际上,它允许您将路径复制到选定的文件作为带引号的字符串并删除部分。chmod +x ~/.local/share/nautilus/scripts/scriptname.sh
file://
要使用它,请在 Nautilus 中选择一个或多个文件,然后右键单击它们。选择Scripts
菜单 -> your_script_name.py
。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from gi.repository import Gtk, Gdk
import sys
import os
import time
import subprocess
import signal
import urllib.parse
import threading
def autoquit(*args):
subprocess.call(['zenity','--info'])
time.sleep(1)
Gtk.main_quit()
def main():
uris = os.getenv("NAUTILUS_SCRIPT_SELECTED_URIS")
new_text = " ".join([ "'" + urllib.parse.unquote(i).replace('file://','') + "'"
for i in uris.split()])
clip = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
if clip.set_text(new_text,-1):
thread = threading.Thread(target=autoquit)
thread.start()
Gtk.main()
if __name__ == '__main__':
try:
main()
except Exception as e:
subprocess.call(['zenity','--info','--text',str(e)])
手动脚本方法,版本 2
这种方法依赖于在粘贴到 之前运行下面的 Python 脚本的想法gnome-terminal
。您可以手动将其gnome-terminal
作为命令 调用,或将其绑定到键盘快捷键。因此,使用快捷方式方法,我会将其绑定到CtrlShiftB(因为它的 B 和 V 在键盘上很接近),并且每次我需要从 Nautilus 粘贴时,我都会点击CtrlShiftB编辑,然后CtrlShiftV粘贴
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from gi.repository import Gtk, Gdk
import subprocess
import urllib.parse
import signal
import sys
def unquote_uri(*args):
uris = args[-2]
new_text = " ".join([ "'" + str(urllib.parse.unquote(i).replace('file://','')) + "'"
for i in uris])
print(new_text)
args[-3].clear()
args[-3].set_text(new_text,-1)
Gtk.main_quit()
def main():
cached = str()
clip = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
clip.request_uris(unquote_uri, None)
signal.signal(signal.SIGINT,signal.SIG_DFL)
Gtk.main()
if __name__ == '__main__': main()
免责声明:答案仍在开发中;稍后可能会添加其他内容/想法
答案2
我有点迟到了,但是我在 Linux Mint MATE(mate-terminal)上看到了这个问题。
看起来,只需抓取剪贴板的内容,然后将其再次传递回剪贴板就足够了。如果是这样的话,那么我们只需要关心测试剪贴板内容是否包含一个或多个有效的文件路径,其余部分则不受影响。
以下命令将删除 Mint 上的 file:// 前缀:
#!/usr/bin/env python
import os
import pyperclip
import time
class ClipboardWatcher():
def __init__(self,latency):
self.clipboard_last = pyperclip.paste()
self.clipboard_now = None
self.latency = latency
def check_clipboard(self):
# assume clipboard is space delimited list of valid paths
as_list = self.clipboard_now.split()
valid_path = [ i for i in as_list if os.path.exists(i) ]
if len(as_list) == len(valid_path): # assumption true
self.clipboard_now = " ".join(valid_path)
return True
return False
def run(self):
while True:
time.sleep(self.latency)
self.clipboard_now = pyperclip.paste()
if self.clipboard_now != self.clipboard_last:
if self.check_clipboard():
pyperclip.copy(self.clipboard_now)
print "Matched:", self.clipboard_now
self.clipboard_last = self.clipboard_now
clippy = ClipboardWatcher(1) # watch every n seconds
clippy.run()
如果你要实现这种方法,那么你可能还需要将其守护进程化。 pyperclip 模块可以通过以下方式获取:
sudo pip install pyperclip