分类 技术 下的文章

VLC 媒体播放器是 最好的媒体播放器 之一。这款跨平台播放器功能丰富,可以播放任何可用的媒体格式。

你会惊讶地发现 VLC 不仅仅是一个视频播放器。它可以对你的媒体文件做很多事情。

我们分享过 使用 VLC 下载 YouTube 视频VLC 技巧

让我再和你分享一个。用 VLC 裁剪视频怎么样?这不是 裁剪视频 的最佳方式,但它可以作为一个选择使用。

使用 VLC 裁剪视频

在 VLC 中裁剪视频本质上意味着从所需部分的开头到结尾录制视频。默认情况下,录制控制工具通常在 VLC 面板中不可见。

让我详细介绍一下步骤。

步骤 1:启用高级控件

要获取控件,你需要使其在主控制面板上可见。

首先选择“ 视图 View ”选项,然后选中“ 高级控件 Advanced Controls ”复选框。现在,如截图所示,出现了带有几个按钮的新控件行。

在 vlc 播放器中启用高级控件视图

步骤 2:打开视频

为了裁剪视频,你需要在 VLC 中打开它。你可以通过“ 媒体 Media > 打开文件 Open File ”在 VLC 播放器中打开视频:

通过 vlc 文件菜单打开媒体文件

或者你可以使用 Nautilus 文件管理器中的 VLC 打开视频文件:

使用 nautilus 文件管理器中的 vlc 播放器打开媒体文件

步骤 3:使用 VLC 的录制功能裁剪视频

打开视频文件后,将时间线设置为所需输出的起点并暂停视频。之后,按“录制”按钮并播放视频。

在起点暂停,按录制键开始录制

当达到所需输出的终点时,暂停视频并再次按下“录制”按钮停止录制。

在终点暂停并按下录制

这应该将裁剪后的输出保存到你的 ~/Videos 目录中。

nautilus 文件管理器中的原始和裁剪后文件

故障排除:无法识别的输出文件

VLC 以 .ts 文件格式录制视频。这在 VLC 中受支持,你可以根据需要使用它。但是 Ubuntu 中的许多其他播放器,包括本地视频播放器,都无法识别该格式。因此,在这种情况下,有两种解决方案。

Gnome-Video 提示安装 GStreamer 包

当你尝试打开文件时,GNOME-Videos 会提示错误并建议安装 Gstreamer 多媒体编解码器。

转换后的视频在 gnome 视频播放器中显示播放错误

你可以点击上图所示的 “ 在 Ubuntu 软件应用中查找 Find in Ubuntu Software ” 按钮,这将打开 Ubuntu 软件中心。你可以在那里安装所需的编解码器包。

根据 GNOME 视频播放器的提示从软件中心安装 gstreamer

同样安装 Gnome-videos 并使用它打开视频将解决问题。

使用 VLC 转换视频文件

如果你不想为此安装任何额外的软件包,你可以使用 VLC 本身将 .ts 文件转换为 mp4 格式以在任何其他播放器中播放。

为此,打开 VLC 并在“ 媒体 Media ”菜单下选择“ 转换/保存 Conver/Save ”选项。

从媒体菜单中选择转换

现在,使用“ 添加 Add ”按钮提供需要转换的文件的位置,然后选择“ 转换/保存 Conver/Save ”,如截图所示。

在媒体转换对话框中选择要转换的文件

选择所需的输出配置(MP4)并为输出设置文件名,然后按“ 开始 Start ”。

在 vlc 媒体转换菜单中设置转换配置和输出文件名

这将开始转换,并根据源的时长决定转换时间。完成后,你可以从 ~/Videos 目录访问转换后的输出。

nautilus 文件管理器中的原始裁剪和转换文件

总结

虽然确实可以使用 VLC 播放器来裁剪视频,但整个过程与专门的 视频编辑器 完全不同。

最大的问题是你需要观看所有裁剪部分才能完成裁剪,如果你要裁剪跨越数分钟的视频的一大部分,这就不方便了。

无论如何,这个很酷的功能在某些情况下可能是一个方便的工具,比如你想要的只是裁剪一个特定的小剪辑或从电影场景中制作一个 Gif。


via: https://itsfoss.com/vlc-trim-video/

作者:Sreenath 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

使用 Lua 配置持久化应用设置。

不是所有的应用都需要配置文件;对很多应用来说,在启动时变得焕然一新对它们更有利。例如,简单的工具就极少需要偏好项和设置在使用过程中保持稳定不变。然而,当你编写一个复杂的应用程序时,如果能让用户设置与应用的交互方式,以及应用与系统交互的方式会很不错。这就是配置文件用来做的事情。本文将讨论一些利用 Lua 进行持久化配置的方法。

选择一种格式

关于配置文件很重要的两点是一致性和可预见性。你不会希望为了保存用户偏好项,将信息转储到文件中,然后再花几天去编码实现“逆向工程”,处理最后出现在文件里的随机信息。

这里用一些常用的 配置文件格式。Lua 有一些库可以处理大多数常用的配置格式;在本文中,我会采用 INI 格式。

安装库

Lua 库的核心仓库是 Luarocks.org。你可以在这个网站搜索库,或者你可以安装并使用 luarocks 终端命令。

Linux 环境中,你可以从发行版的软件仓库中下载它,例如:

$ sudo dnf install luarocks

在 macOS 上,请使用 MacPorts 或者 Homebrew。在 Windows 上,请使用 Chocolatey

luarocks 安装后,你可以使用 search 子命令来搜索一个恰当的库。如果你不知道库的名字,可以通过关键词来搜索这个库,例如 ini、xml或者json,这取决于你想要用这个库做什么。打个比方,你可以搜索inifile`, 这个库被我用来解析 INI 格式的文本文件。

$ luarocks search inifile
Search results:
inifile
 1.0-2 (rockspec) - https://luarocks.org
 1.0-2 (src) - https://luarocks.org
 1.0-1 (rockspec) - https://luarocks.org
 [...]

一个开发者容易犯的错误是在系统上安装了这个库却忘了把它和应用打包。这会给没有安装这个库的用户带来麻烦。为了防止这个问题发生,可以使用 --tree 选项将它安装在项目的本地文件夹中。如果你没有这个项目文件夹,那就先创建这个文件夹再安装库:

$ mkdir demo
$ cd demo
$ luarocks install --tree=local inifile

--tree 选项指示 luarocks 创建一个新文件夹并在其中安装你的库,例如这个例子中的 local 文件夹。 使用这个简单的技巧,你可以将所有你项目要使用的依赖项直接安装到项目文件夹中。

配置代码

首先,在一个名 myconfig.ini 的文件中创建一些 INI 数据。

[example]
name=Tux
species=penguin
enabled=false

[demo]
name=Beastie
species=demon
enabled=false

将这个文件保存到你的主目录下,命名为 myconfig.ini, 不要 存到项目文件夹下。你通常会希望配置文件独立于你的文件存在,这样当用户卸载你的应用时,使用应用时产生的数据可以保存在系统中。有些用户会删除不重要的配置文件,但大多数不会。最终,如果他们要重装这个应用,还会保留着所有的用户偏好项。

配置文件的位置以技术来说并不重要,但每一个操作系统都有存储它们的特定或者默认的路径。在 Linux 中,这个路径由 Freedesktop 规范 指定。它规定配置文件被保存在一个名为 ~/.config 的隐藏文件夹中。为了操作时更加清晰明确,可以在主目录下存储配置文件,以便于使用和寻找。

创建第二个文件,命名为 main.lua,并在你喜欢的文本编辑器中打开它。

首先,你必须告诉 Lua 你将想要使用的附加库放置在哪里。package.path 变量决定了 Lua 到哪里去寻找这些库。你可以从终端中查看 Lua 默认的包地址:

$ Lua
> print(package.path)
./?.lua;/usr/share/lua/5.3/?.lua;/usr/share/lua/5.3/?/init.lua;/usr/lib64/lua/5.3/?.lua;/usr/lib64/lua/5.3/?/init.lua

在你的 Lua 代码中,将你本地库的路径添加到 package.path 中:

package.path = package.path .. ';local/share/lua/5.3/?.lua

使用 Lua 解析 INI 文件

当包的位置确定以后,下一件事就是引入 inifile 库并处理一些操作系统逻辑。即使这是一个很简单的应用,代码也需要从操作系统获取到用户主目录的路径,并建立在必要时将文件系统路径返回给操作系统的通信方式。

package.path = package.path .. ';local/share/lua/5.3/?.lua
inifile = require('inifile')

-- find home directory
home = os.getenv('HOME')

-- detect path separator
-- returns '/' for Linux and Mac
-- and '\' for Windows
d = package.config:sub(1,1)

现在你可使用 inifile 来从配置文件解析数据到 Lua 表中。一旦这些数据被导入进表中,你可以像查询其他的 Lua 表一样查询它。

-- parse the INI file and
-- put values into a table called conf
conf = inifile.parse(home .. d .. 'myconfig.ini')

-- print the data for review
print(conf['example']['name'])
print(conf['example']['species'])
print(conf['example']['enabled'])

在终端中运行代码可以看见结果:

$ lua ./main.lua
Tux
penguin
false

这看起来是正确的。试试在 demo 块中执行同样的操作。

使用 INI 格式存储数据

不是所有用来解析的库都会读写数据(通常被称为 \_编码 和 解码),但是 inifile 会这样做。这意味着你可以使用它对配置文件进行修改。

为了改变配置文件中的值,你可以对被解析的表中的变量进行设置,然后把表重写回配置文件中。

-- set enabled to true
conf['example']['enabled'] = true
conf['demo']['enabled'] = true

-- save the change
inifile.save(home .. d .. 'myconfig.ini', conf)

现在再来看看配置文件:

$ cat ~/myconfig.ini
[example]
name=Tux
species=penguin
enabled=true

[demo]
name=Beastie
species=demon
enabled=true

配置文件

按照用户的设想来存储数据对程序来说是至关重要的。幸运的是,这对工程师来说是一个很常规的任务,大多数工作可能早已被完成了。只要找到一个好用的库完成开放格式下编码和解码,你就能为用户提供一致且持续的体验。

以下是完整的演示代码,可供参考。

package.path = package.path .. ';local/share/lua/5.3/?.lua'
inifile = require('inifile')

-- find home directory
home = os.getenv('HOME')

-- detect path separator
-- returns '/' for Linux and Mac
-- and '\' for Windows
d = package.config:sub(1,1)

-- parse the INI file and
-- put values into a table called conf
conf = inifile.parse(home .. d .. 'myconfig.ini')

-- print the data for review
print(conf['example']['name'])
print(conf['example']['species'])
print(conf['example']['enabled'])

-- enable Tux
conf['example']['enabled'] = true

-- save the change
inifile.save(home .. d .. 'myconfig.ini', conf)

via: https://opensource.com/article/21/6/parsing-config-files-lua

作者:Seth Kenlon 选题:lujun9972 译者:hadisi1993 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

开源的 PSCP 程序可以轻松地在 Windows 和 Linux 计算机之间传输文件和文件夹。

你是否正在寻找一种将文件从 Windows 计算机快速传输到 Linux 计算机并再次传输回来的方法?开源的 PSCP 程序可以轻松传输文件和文件夹,当然它是开源的。

在 Windows 中设置 PATH

了解如何在 Windows 中设置命令路径可以更轻松地使用 PSCP 等方便的程序。如果你不熟悉该过程,请阅读 如何在 Windows 上设置 PATH

使用 PSCP

PSCP(PuTTY 安全复制协议)是一个命令行工具,用于将文件和文件夹从 Windows 计算机传输到 Linux 计算机。

  • 网站 下载 pscp.exe
  • pscp.exe 移动到 PATH 中的文件夹(例如,如果你按照 Opensource.com 上的 PATH 教程进行操作,则为 Desktop\App)。如果你没有设置 PATH 变量,你也可以将 pscp.exe 移动到保存要传输的文件的文件夹中。
  • 使用 Windows 任务栏中的搜索栏在 Windows 计算机上打开 Powershell(在搜索栏中输入 powershell。)
  • 输入 pscp -version 以确认你的计算机可以找到该命令。

IP 地址

在进行传输之前,你必须知道目标计算机的 IP 地址或完全限定域名。假设它是同一网络上的计算机,并且你没有运行 DNS 服务器来解析计算机名称,你可以在 Linux 机器上使用 ip 命令找到目标 IP 地址:

[linux]$ ip addr show |grep 'inet '
inet 127.0.0.1/8 scope host lo
inet 192.168.1.23/24 brd 10.0.1.255 scope global noprefixroute eth0

在所有情况下,127.0.0.1 都是计算机仅用于与自身通信的环回地址,因此在此示例中,正确的地址是 192.168.1.23。在你的系统上,IP 地址可能不同。如果你不确定哪个是哪个,你可以连续尝试每个,直到找到正确的(然后在某处写下来!)

或者,你可以查看路由器的设置,其中列出了通过 DHCP 分配的所有地址。

防火墙和服务器

pscp 命令使用 OpenSSH 协议,因此你的 Linux 计算机必须运行 OpenSSH 服务器软件,并且防火墙必须允许 SSH 流量。

如果你不确定你的 Linux 机器是否正在运行 SSH,请在 Linux 机器上运行以下命令:

[linux]$ sudo systemctl enable --now sshd

要确保你的防火墙允许 SSH 流量,请运行以下命令:

[linux]$ sudo firewall-cmd --add-servicessh --permanent

有关 Linux 上的防火墙的更多信息,请阅读 使用防火墙使 Linux 更强大

传输文件

在这个例子中,我有一个名为 pscp-test.txt 的文件,我想将它从我的 Windows 计算机上的 C:\Users\paul\Documents 传输到我的目标 Linux 计算机主目录 /home/paul

现在你已经有了 pscp 命令和目标地址,你可以传输测试文件 pscp-test.txt。打开 Powershell 并使用 dir 命令切换到示例文件所在的 Documents 文件夹:

PS> dir %USERPROFILE%\Documents\

现在执行传输:

PS> pscp pscp-test.txt [email protected]:/home/paul
| Password:
End of keyboard-interactive prompts from server
pscp-test.txt | 0 kb | 0.0 kB/s | ETA: 00:00:00 | 100%

这是语法,逐字逐句来:

  • pscp:用于传输文件的命令。
  • pscp-test.txt 是你要从 Windows 传输的文件的名称。
  • [email protected] 是我在 Linux 计算机上的用户名,以及 Linux 计算机的 IP 地址。你必须将其替换为你自己的用户和目的地信息。请注意,pscp 需要目标计算机上的目标路径,而 IP 地址末尾的 :/home/paul 指定我希望将文件复制到我的主文件夹。

对 Linux 计算机进行身份验证后,pscp-test.txt 文件将传输到 Linux 计算机。

验证已传输

在你的 Linux 计算机上,打开终端并使用 ls 命令验证文件 pscp-test.txt 是否出现在你的主目录中。

[linux]$ ls
Documents
Downloads
Music
Pictures
pscp-test.txt

从 Linux 系统复制文件

你不仅限于将文件复制到 Linux 系统。使用 pscp,你还可以将文件从 Linux 复制到 Windows。语法是一样的,只是反过来:

PS> pscp [email protected]:/home/paul/pscp-test.txt %USERPROFILE%\Documents\pscp-win.txt

这是语法:

  • pscp:用于传输文件的命令。
  • [email protected]:/home/paul/pscp-test.txt 是我在 Linux 计算机上的用户名、Linux 计算机的 IP 地址,以及我要复制的文件的路径。
  • %USERPROFILE%\Documents 是我的 Windows 计算机上我要保存文件的位置。 请注意,在将文件复制回我的 Windows 计算机时,我可以给它一个新名称,例如 pscp-win.txt,以区别于原始文件。 当然,你不必重命名文件,但对于本演示来说,它是一个有用的快捷方式。

打开文件管理器以验证 pscp-win.txt 文件是否已从 Linux 计算机复制到 Windows C:\Users\paul\Documents 下。

Image of a file manager.

远程复制

借助开源 pscp 命令的强大功能,你可以访问家中的任何计算机、拥有帐户的服务器,甚至是移动设备和 边缘设备


via: https://opensource.com/article/22/10/transfer-files-windows-linux-pscp

作者:Paul 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

awk 和 Groovy 相辅相成,可以创建强大、有用的脚本。

最近我写了一个使用 Groovy 脚本来清理我的音乐文件中的标签的系列。我开发了一个 框架,可以识别我的音乐目录的结构,并使用它来遍历音乐文件。在该系列的最后一篇文章中,我从框架中分离出一个实用类,我的脚本可以用它来处理文件。

这个独立的框架让我想起了很多 awk 的工作方式。对于那些不熟悉 awk 的人来说,你学习下这本电子书:

《awk 实用指南》

我从 1984 年开始大量使用 awk,当时我们的小公司买了第一台“真正的”计算机,它运行的是 System V Unix。对我来说,awk 是非常完美的:它有 关联内存 associative memory ——将数组视为由字符串而不是数字来索引的。它内置了正则表达式,似乎专为处理数据而生,尤其是在处理数据列时,而且结构紧凑,易于学习。最后,它非常适合在 Unix 工作流使用,从标准输入或文件中读取数据并写入到输出,数据不需要经过其他的转换就出现在了输入流中。

说 awk 是我日常计算工具箱中的一个重要部分一点也不为过。然而,在我使用 awk 的过程中,有几件事让我感到不满意。

可能主要的问题是 awk 善于处理以分隔字段呈现的数据,但很奇怪它不善于处理 CSV 文件,因为 CSV 文件的字段被引号包围时可以嵌入逗号分隔符。另外,自 awk 发明以来,正则表达式已经有了很大的发展,我们需要记住两套正则表达式的语法规则,而这并不利于编写无 bug 的代码。一套这样的规则已经很糟糕了

由于 awk 是一门简洁的语言,因此它缺少很多我认为有用的东西,比如更丰富的基础类型、结构体、switch 语句等等。

相比之下,Groovy 拥有这些能力:可以使用 OpenCSV 库,它很擅长处理 CSV 文件、Java 正则表达式和强大的匹配运算符、丰富的基础类型、类、switch 语句等等。

Groovy 所缺乏的是简单的面向管道的概念,即把要处理数据作为一个传入的流,以及把处理过的数据作为一个传出的流。

但我的音乐目录处理框架让我想到,也许我可以创建一个 Groovy 版本的 awk “引擎”。这就是我写这篇文章的目的。

安装 Java 和 Groovy

Groovy 是基于 Java 的,需要先安装 Java。最新的、合适的 Java 和 Groovy 版本可能都在你的 Linux 发行版的软件库中。Groovy 也可以按照 Groovy 主页 上的说明进行安装。对于 Linux 用户来说,一个不错的选择是 SDKMan,它可以用来获得多个版本的 Java、Groovy 和其他许多相关工具。在这篇文章中,我使用的是 SDK 的版本:

  • Java:OpenJDK 11 的 11.0.12 的开源版本
  • Groovy:3.0.8

使用 Groovy 创建 awk

这里的基本想法是将打开一个或多个文件进行处理、将每行分割成字段、以及提供对数据流的访问等复杂情况封装在三个部分:

  • 在处理数据之前
  • 在处理每行数据时
  • 在处理完所有数据之后

我并不打算用 Groovy 来取代 awk。相反,我只是在努力实现我的典型用例,那就是:

  • 使用一个脚本文件而不是在命令行写代码
  • 处理一个或多个输入文件
  • 设置默认的分隔符为 |,并基于这个分隔符分割所有行
  • 使用 OpenCSV 完成分割工作(awk 做不到)

框架类

下面是用 Groovy 类实现的 “awk 引擎”:

@Grab('com.opencsv:opencsv:5.6')
import com.opencsv.CSVReader
public class AwkEngine {
    // With admiration and respect for
    //     Alfred Aho
    //     Peter Weinberger
    //     Brian Kernighan
    // Thank you for the enormous value
    // brought my job by the awk
    // programming language
    Closure onBegin
    Closure onEachLine
    Closure onEnd
    private String fieldSeparator
    private boolean isFirstLineHeader
    private ArrayList<String> fileNameList
    public AwkEngine(args) {
        this.fileNameList = args
        this.fieldSeparator = "|"
        this.isFirstLineHeader = false
    }
    public AwkEngine(args, fieldSeparator) {
        this.fileNameList = args
        this.fieldSeparator = fieldSeparator
        this.isFirstLineHeader = false
    }
    public AwkEngine(args, fieldSeparator, isFirstLineHeader) {
        this.fileNameList = args
        this.fieldSeparator = fieldSeparator
        this.isFirstLineHeader = isFirstLineHeader
    }
    public void go() {
        this.onBegin()
        int recordNumber = 0
        fileNameList.each { fileName ->
            int fileRecordNumber = 0
            new File(fileName).withReader { reader ->
                def csvReader = new CSVReader(reader,
                    this.fieldSeparator.charAt(0))
                if (isFirstLineHeader) {
                    def csvFieldNames = csvReader.readNext() as
                        ArrayList<String>
                    csvReader.each { fieldsByNumber ->
                        def fieldsByName = csvFieldNames.
                            withIndex().
                            collectEntries { name, index ->
                                [name, fieldsByNumber[index]]
                            }
                        this.onEachLine(fieldsByName,
                                recordNumber, fileName,
                                fileRecordNumber)
                        recordNumber++
                        fileRecordNumber++
                    }
                } else {
                    csvReader.each { fieldsByNumber ->
                        this.onEachLine(fieldsByNumber,
                            recordNumber, fileName,
                            fileRecordNumber)
                        recordNumber++
                        fileRecordNumber++
                    }
                }
            }
        }
        this.onEnd()
    }
}

虽然这看起来是相当多的代码,但许多行是因为太长换行了(例如,通常你会合并第 38 行和第 39 行,第 41 行和第 42 行,等等)。让我们逐行看一下。

第 1 行使用 @Grab 注解从 Maven Central 获取 OpenCSV 库的 5.6 本周。不需要 XML。

第 2 行我引入了 OpenCSV 的 CSVReader

第 3 行,像 Java 一样,我声明了一个 public 实用类 AwkEngine

第 11-13 行定义了脚本所使用的 Groovy 闭包实例,作为该类的钩子。像任何 Groovy 类一样,它们“默认是 public”,但 Groovy 将这些字段创建为 private,并对其进行外部引用(使用 Groovy 提供的 getter 和 setter 方法)。我将在下面的示例脚本中进一步解释这个问题。

第 14-16 行声明了 private 字段 —— 字段分隔符,一个指示文件第一行是否为标题的标志,以及一个文件名的列表。

第 17-31 行定义了三个构造函数。第一个接收命令行参数。第二个接收字段的分隔符。第三个接收指示第一行是否为标题的标志。

第 31-67 行定义了引擎本身,即 go() 方法。

第 33 行调用了 onBegin() 闭包(等同于 awk 的 BEGIN {} 语句)。

第 34 行初始化流的 recordNumber(等同于 awk 的 NR 变量)为 0(注意我这里是从 00 而不是 1 开始的)。

第 35-65 行使用 each {} 来循环处理列表中的文件。

第 36 行初始化文件的 fileRecordNumber(等同于 awk 的 FNR 变量)为 0(从 0 而不是 1 开始)。

第 37-64 行获取一个文件对应的 Reader 实例并处理它。

第 38-39 行获取一个 CSVReader 实例。

第 40 行检测第一行是否为标题。

如果第一行是标题,那么在 41-42 行会从第一行获取字段的标题名字列表。

第 43-54 行处理其他的行。

第 44-48 行把字段的值复制到 name:value 的映射中。

第 49-51 行调用 onEachLine() 闭包(等同于 awk 程序 BEGIN {}END {} 之间的部分,不同的是,这里不能输入执行条件),传入的参数是 name:value 映射、处理过的总行数、文件名和该文件处理过的行数。

第 52-53 行是处理过的总行数和该文件处理过的行数的自增。

如果第一行不是标题:

第 56-62 行处理每一行。

第 57-59 调用 onEachLine() 闭包,传入的参数是字段值的数组、处理过的总行数、文件名和该文件处理过的行数。

第 60-61 行是处理过的总行数和该文件处理过的行数的自增。

第 66 行调用 onEnd() 闭包(等同于 awk 的 END {})。

这就是该框架的内容。现在你可以编译它:

$ groovyc AwkEngine.groovy

一点注释:

如果传入的参数不是一个文件,编译就会失败,并出现标准的 Groovy 堆栈跟踪,看起来像这样:

Caught: java.io.FileNotFoundException: not-a-file (No such file or directory)
java.io.FileNotFoundException: not-a-file (No such file or directory)
at AwkEngine$_go_closure1.doCall(AwkEngine.groovy:46)

OpenCSV 可能会返回 String[] 值,不像 Groovy 中的 List 值那样方便(例如,数组没有 each {})。第 41-42 行将标题字段值数组转换为 list,因此第 57 行的 fieldsByNumber 可能也应该转换为 list。

在脚本中使用这个框架

下面是一个使用 AwkEngine 来处理 /etc/group 之类由冒号分隔并没有标题的文件的简单脚本:

def ae = new AwkEngine(args, ':')
int lineCount = 0
ae.onBegin = {
    println “in begin”
}
ae.onEachLine = { fields, recordNumber, fileName, fileRecordNumber ->
    if (lineCount < 10)
        println “fileName $fileName fields $fields”
    lineCount++
}
ae.onEnd = {
    println “in end”
    println “$lineCount line(s) read”
}
ae.go()

第 1 行 调用的有两个参数的构造函数,传入了参数列表,并定义冒号为分隔符。

第 2 行定义一个脚本级的变量 lineCount,用来记录处理过的行数(注意,Groovy 闭包不要求定义在外部的变量为 final)。

第 3-5 行定义 onBegin() 闭包,在标准输出中打印出 “in begin” 字符串。

第 6-10 行定义 onEachLine() 闭包,打印文件名和前 10 行字段,无论是否为前 10 行,处理过的总行数 lineCount 都会自增。

第 11-14 行定义 onEnd() 闭包,打印 “in end” 字符串和处理过的总行数。

第 15 行运行脚本,使用 AwkEngine

像下面一样运行一下脚本:

$ groovy Test1Awk.groovy /etc/group
in begin
fileName /etc/group fields [root, x, 0, ]
fileName /etc/group fields [daemon, x, 1, ]
fileName /etc/group fields [bin, x, 2, ]
fileName /etc/group fields [sys, x, 3, ]
fileName /etc/group fields [adm, x, 4, syslog,clh]
fileName /etc/group fields [tty, x, 5, ]
fileName /etc/group fields [disk, x, 6, ]
fileName /etc/group fields [lp, x, 7, ]
fileName /etc/group fields [mail, x, 8, ]
fileName /etc/group fields [news, x, 9, ]
in end
78 line(s) read
$

当然,编译框架类生成的 .class 文件需要在 classpath 中,这样才能正常运行。通常你可以用 jar 把这些 class 文件打包起来。

我非常喜欢 Groovy 对行为委托的支持,这在其他语言中需要各种诡异的手段。许多年来,Java 需要匿名类和相当多的额外代码。Lambda 已经在很大程度上解决了这个问题,但它们仍然不能引用其范围之外的非 final 变量。

下面是另一个更有趣的脚本,它很容易让人想起我对 awk 的典型使用方式:

def ae = new AwkEngine(args, ';', true)
ae.onBegin = {
    // nothing to do here
}
def regionCount = [:]
    ae.onEachLine = { fields, recordNumber, fileName, fileRecordNumber ->
        regionCount[fields.REGION] =
            (regionCount.containsKey(fields.REGION) ?
                regionCount[fields.REGION] : 0) +
            (fields.PERSONAS as Integer)
}
ae.onEnd = {
    regionCount.each { region, population ->
        println “Region $region population $population”
    }
}
ae.go()

第 1 行调用了三个函数的构造方法,true 表示这是“真正的 CSV” 文件,第一行为标题。由于它是西班牙语的文件,因此它的逗号表示数字的,标准的分隔符是分号。

第 2-4 行定义 onBegin() 闭包,这里什么也不做。

第 5 行定义一个(空的)LinkedHashmap,键是 String 类型,值是 Integer 类型。数据文件来自于智利最近的人口普查,你要在这个脚本中计算出智利每个地区的人口数量。

第 6-11 行处理文件中的行(加上标题一共有 180,500 行)—— 请注意在这个案例中,由于你定义 第 1 行为 CSV 列的标题,因此 fields 参数会成为 LinkedHashMap<String,String> 实例。

第 7-10 行是 regionCount 映射计数增加,键是 REGION 字段的值,值是 PERSONAS 字段的值 —— 请注意,与 awk 不同,在 Groovy 中你不能在赋值操作的右边使用一个不存在的映射而期望得到空值或零值。

第 12-16 行,打印每个地区的人口数量。

第 17 行运行脚本,调用 AwkEngine

像下面一样运行一下脚本:

$ groovy Test2Awk.groovy ~/Downloads/Censo2017/ManzanaEntidad_CSV/Censo*csv
Region 1 population 330558
Region 2 population 607534
Region 3 population 286168
Region 4 population 757586
Region 5 population 1815902
Region 6 population 914555
Region 7 population 1044950
Region 8 population 1556805
Region 16 population 480609
Region 9 population 957224
Region 10 population 828708
Region 11 population 103158
Region 12 population 166533
Region 13 population 7112808
Region 14 population 384837
Region 15 population 226068
$

以上为全部内容。对于那些喜欢 awk 但又希望得到更多的东西的人,我希望你能喜欢这种 Groovy 的方法。


via: https://opensource.com/article/22/9/awk-groovy

作者:Chris Hermansen 选题:lkxed 译者:lxbwolf 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

打算为你的项目开发工作安装 Python 3.11?下面是如何在 Ubuntu 等发行版中安装 Python 3.11 的方法。

Python 3.11 于 2022 年 10 月 25 日发布,并声称比之前的 Python 3.10 版本快 10% - 60%。

一如既往,3.11 中的功能和改进列表明显较多。下面是一个简介:

  • 错误回溯更明确,可以指出导致错误的确切语句。
  • 引入异常组和新的 except* 语法。
  • 你可以在基础表达式中添加自定义文本,以便在你的代码中更好地处理错误。
  • 引入 Variadic 泛型,允许在 Python 数值库(如 NumPy)中使用类似数组的结构。
  • 字典类型 TypedDict 得到了改进,现在你可以指定个别字典项目是必须的还是可选的。
  • 引入了 Self 注解,允许类返回它们自己的类型实例。

还有很多,你可以在官方的 3.11 亮点页面 上详细了解。

Linux 发行版中的当前 Python 版本

Ubuntu 22.04 LTS 带有 Python 3.10,而最近发布的 Ubuntu 22.10 Kinetic Kudu 也是同样的版本。然而, Kinetick Kudu 可能会在几周内采用 3.11。

另外,Fedora 37 已经有了 Python 3.11 RC2,并将提供该版本。

所以,如果你正在运行 Ubuntu 22.04 LTS、Linux Mint 21 或任何基于 Ubuntu-LTS 的发行版,这里是你如何通过 PPA 安装 Python 3.11 的方法。

注意:谨慎地使用这个方法。确保你知道你在做什么,因为替换 Linux 发行版的基础 Python 版本可能会导致系统不稳定。许多默认的应用程序和软件包都依赖于 3.10 版本。

如何在 Ubuntu 和相关发行版中安装 Python 3.11

打开终端提示,添加以下 PPA:

sudo add-apt-repository ppa:deadsnakes/ppa

使用下面的命令刷新缓存:

sudo apt update 

并使用下面的命令安装 Python 3.11:

sudo apt install python3.11

在 Ubuntu 22.04 LTS 中安装 Python 3.11

设置默认的 Python 版本

理论上,你可以在 Linux 发行版中安装多个版本的 Python,但只能默认一个版本。将 Python 3.11 设置为默认版本需要一些额外的步骤。请跟我做。

然而,在这之前,请确保你知道哪些应用程序依赖于 Python 3.10。你可以使用 apt-cache rdepends 命令轻松地找到它,如下所示:

debugpoint@debugpoint-22-04:~$ apt-cache rdepends python3.10
python3.10
Reverse Depends:
python3.10-dbg
python3.10-venv
python3.10-full
libpython3.10-testsuite
idle-python3.10
idle-python3.10
python3.10-minimal
python3.10-doc
python3.10-dev
python3
[截断]
python3
python3-uno
python3-all
gedit

使用 Python 3.11 作为默认的 Python3

首先,从终端使用以下命令检查当前的默认版本:

python3 --version

使用 update-alternatives 来创建 python3 的符号链接:

sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 1
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 2

并通过命令选择哪一个作为 Python3 使用:

sudo update-alternatives --config python3

设置默认的 Python 版本为 3.11

现在你可以开始在你当前的 Ubuntu 版本中使用最新的 Python 来进行工作/学习了。你可以使用上述命令切换到库存版本,并随时改变版本。

如果你使用上述安装方法切换到 3.11,那么请确保你检查所有必要的应用程序,看它们是否工作正常。

最后,如果你遇到问题,请在评论区告诉我。


via: https://www.debugpoint.com/install-python-3-11-ubuntu/

作者:Arindam 选题:lkxed 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

本指南旨在帮助你在 Firefox、Chrome、Chromium 和 Edge 等流行的网页浏览器中启用深色模式。

我们都喜欢深色模式。与标准浅色模式相比,许多人更喜欢它。许多桌面应用原生提供深色模式,而一些应用则是通过桌面环境的底层模式适应深色模式。

不可否认,我们都在网页浏览器上花费了很多时间。我们很少使用桌面应用(除非你从事专门的工作,例如视频编辑等)。因此,当你花费大量时间在浏览器中阅读和学习时,你始终可以选择深色模式。不过,对于网页浏览器,启用深色模式的方法略有不同。

本指南为你提供了在 Firefox、Chromium、Chrome 和 Edge 浏览器中启用深色模式的简单步骤。

在网页浏览器中启用深色模式

在 Firefox 中启用深色模式

打开 Firefox 并点击右上角的菜单。

单击 “ 设置 Settings > 扩展和主题 Extension and Themes ”。

选择 “ 深色主题 Dark Theme ” 并点击 “ 启用 enable ”。你应该会看到深色模式已应用于 Firefox。

Enable dark mode in Firefox

在 Firefox 浏览器中启用深色模式

Firefox in Dark Mode

深色模式下的 Firefox

要将其还原,请按照相同的步骤并选择浅色主题。

Chromium 和 Chrome 中的深色模式

默认情况下,Chromium 或 Chrome 不会预安装任何深色主题。因此,你需要前往 Chrome 应用商店并下载你想要的深色主题。对于本指南,我会推荐超过一百万用户使用的 “Morpheon Dark” 主题。

从 Chromium 浏览器打开 Morpheon Dark 主题页面(以下链接)。

Chrome 应用商店中的 Morpheon Dark 主题

点击 “ 添加到 Chrome Add To Chrome ” 按钮。它应该会在 Chrome 中启用。

你可能想探索 Chrome 应用店中提供的其他深色或浅色主题。 访问此页面获取所有深色主题的集合

但是,你应该要记住的一件事是:此主题不会更改设置或上下文菜单,这是显而易见的。因为它只是改变了浏览器窗口,而这些菜单(有时)是操作系统本身的一部分。

Chromium Dark Theme

Chromium 深色主题

对 Chrome 浏览器也遵循相同的步骤。

Edge 浏览器 – 深色模式

但是,Edge 浏览器 默认带有更好的深色主题。它允许你从设置中使用 GTK+、浅色和深色模式。

打开 Edge 浏览器,点击右上角的三个小点。

转到 “ 外观 Appearance ” 并选择 “ 深色 Dark ”。这样应该就好了。

Edge 的这种深色主题实现更好,因为它改变了上下文菜单和地址栏。

Edge in Dark Theme

深色主题的 Edge

总结

如果你是高级用户,你可能不需要本指南。你可以自己弄清楚。

但我们为所有读者涵盖了所有基础到高级教程。许多新的 Linux 用户可能不知道如何在浏览器中启用深色模式。

所以,就是说,我希望这对你和其他人有帮助。如果你遇到任何问题,请在下面的评论框中告诉我。


via: https://www.debugpoint.com/dark-mode-browser/

作者:Arindam 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux 中国 荣誉推出