2018年12月

使用 cowsay 实用程序将牛的话语带到你的终端输出。

欢迎来到 Linux 命令行玩具第四天。如果这是你第一次访问这个系列,你可能会问自己,什么是命令行玩具。我们也在考虑这一点,但是一般来说,这可能是一个游戏,或者任何简单的娱乐,可以帮助你在终端玩得开心。

你们中的一些人会见过我们之前的选中的各种玩具,但是我们希望至少有一个对每个人来说都是新的。因为几乎所有我告诉他这个系列的人都已经问过它了,所以今天的选中的玩具是必须提及的。

你也不会认为我们会在不提及 cowsay 的情况下完成这个系列,对吧?

cowsay 是一个神奇的实用程序,它将文本作为 ASCII 艺术牛的讲话文本输出。

你可能会发现 cowsay 打包在你的默认存储库中,甚至可能已经安装了。对我来说,在 Fedora,像这样安装:

$ sudo dnf install -y cowsay

然后,用 cowsay 调用它,然后是你的消息。也许你想到昨天我们谈到的 fortune 应用 连接起来。

$ fortune | cowsay
 _________________________________________
/ If at first you do succeed, try to hide \
\ your astonishment.                      /
 -----------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

就这样!cowsay 还有点小变体,称为 cow 文件,通常可以在 /usr/share/cowsay 找到 ,要查看系统上可用的 cow 文件,请在 cowsay 之后使用 -l 。然后,用 -f 试试其中之一。

$ cowsay -f dragon "Run for cover, I feel a sneeze coming on."
 _______________________________________
/ Run for cover, I feel a sneeze coming \
\ on.                                   /
 ---------------------------------------
      \                    / \  //\
       \    |\___/|      /   \//  \\
            /0  0  \__  /    //  | \ \    
           /     /  \/_/    //   |  \  \  
           @_^_@'/   \/_   //    |   \   \ 
           //_^_/     \/_ //     |    \    \
        ( //) |        \///      |     \     \
      ( / /) _|_ /   )  //       |      \     _\
    ( // /) '/,_ _ _/  ( ; -.    |    _ _\.-~        .-~~~^-.
  (( / / )) ,-{        _      `-.|.-~-.           .~         `.
 (( // / ))  '/\      /                 ~-. _ .-~      .-~^-.  \
 (( /// ))      `.   {            }                   /      \  \
  (( / ))     .----~-.\        \-'                 .~         \  `. \^-.
             ///.----..>        \             _ -~             `.  ^-`  ^-_
               ///-._ _ _ _ _ _ _}^ - - - - ~                     ~-- ,.-~
                                                                  /.-~

我对 cowsay 的真正不满是,我今天没有足够的时间来为牛的挤奶 —— 一语双关。牛排价格太高了,我只是开个玩笑。

更严重的是,我已经完全忘记了 cowsay 直到我在学习 Ansible 的剧本时再次遇到它。如果你碰巧安装了 cowsay,当你运行Ansible 的剧本时,你会从一队奶牛那里获得输出。例如,运行这个剧本:

- hosts:
    - localhost
  tasks:
    - action: ping

可能会给你以下信息:

$ ansible-playbook playbook.yml
 __________________
< PLAY [localhost] >
 ------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

 ________________________
< TASK [Gathering Facts] >
 ------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

ok: [localhost]
 _____________
< TASK [ping] >
 -------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

ok: [localhost]
 ____________
< PLAY RECAP >
 ------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

localhost                  : ok=2    changed=0    unreachable=0    failed=0  

cowsay 在 GPLv3 许可证下可用,您可以在 GitHub 上找到 它的 Perl 源代码。我也见过其他语言的版本,所以可以看看其他变体;例如,这是 R 语言版。用你选择的语言实现你自己的版本可能是一项有趣的编程学习任务。

既然讲完了 cowsay,我们可以去更绿色的牧场了。

你有希望我来介绍的喜欢的命令行玩具吗?这个系列的排期大部分都填好了,但我还有一些空位方。在下面的评论中让我知道,我会来看看。如果有空间,我会尝试把它包括进去。如果没有,但是我收到了一些好的意见,我在结尾提及。

看看昨天的玩具,如何给你的 Linux 终端带来好运,明天再来看看另一个!


via: https://opensource.com/article/18/12/linux-toy-cowsay

作者:Jason Baker 选题:lujun9972 译者:heguangzhi 校对:wxy

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

不要只测试已有系统,强安全要求更积极主动的策略。

我们当中有多少人曾说出过下面这句话:“我希望这能起到作用!”?

毫无疑问,我们中的大多数人可能都不止一次地说过这句话。这句话不是用来激发信心的,相反它揭示了我们对自身能力和当前正在测试的功能的怀疑。不幸的是,这句话非常好地描述了我们传统的安全模型。我们的运营基于这样的假设,并希望我们实施的控制措施 —— 从 web 应用的漏扫到终端上的杀毒软件 —— 防止恶意的病毒和软件进入我们的系统,损坏或偷取我们的信息。

渗透测试通过积极地尝试侵入网络、向 web 应用注入恶意代码或者通过发送钓鱼邮件来传播病毒等等这些步骤来避免我们对假设的依赖。由于我们在不同的安全层面上来发现和渗透漏洞,手动测试无法解决漏洞被主动打开的情况。在安全实验中,我们故意在受控的情形下创造混乱,模拟事故的情形,来客观地检测我们检测、阻止这类问题的能力。

“安全实验为分布式系统的安全性实验提供了一种方法,以建立对抗恶意攻击的能力的信心。”

在分布式系统的安全性和复杂性方面,需要反复地重申混沌工程界的一句名言,“希望不是一种有效的策略”。我们多久会主动测试一次我们设计或构建的系统,来确定我们是否已失去对它的控制?大多数组织都不会发现他们的安全控制措施失效了,直到安全事件的发生。我们相信“安全事件不是侦察措施”,而且“希望不要出事也不是一个有效的策略”应该是 IT 专业人士执行有效安全实践的口号。

行业在传统上强调预防性的安全措施和纵深防御,但我们的任务是通过侦探实验来驱动对安全工具链的新知识和见解。因为过于专注于预防机制,我们很少尝试一次以上地或者年度性地手动测试要求的安全措施,来验证这些控件是否按设计的那样执行。

随着现代分布式系统中的无状态变量的不断改变,人们很难充分理解他们的系统的行为,因为会随时变化。解决这个问题的一种途径是通过强大的系统性的设备进行检测,对于安全性检测,你可以将这个问题分成两个主要方面:测试,和我们称之为实验的部分。测试是对我们已知部分的验证和评估,简单来说,就是我们在开始找之前,要先弄清楚我们在找什么。另一方面,实验是去寻找获得我们之前并不清楚的见解和知识。虽然测试对于一个成熟的安全团队来说是一项重要实践,但以下示例会有助于进一步地阐述两者之间的差异,并对实验的附加价值提供一个更为贴切的描述。

示例场景:精酿啤酒

思考一个用于接收精酿啤酒订单的 web 服务或者 web 应用。

这是这家精酿啤酒运输公司的一项重要服务,这些订单来自客户的移动设备、网页,和通过为这家公司精酿啤酒提供服务的餐厅的 API。这项重要服务运行在 AWS EC2 环境上,并且公司认为它是安全的。这家公司去年成功地通过了 PCI 规则,并且每年都会请第三方进行渗透测试,所以公司认为这个系统是安全的。

这家公司有时一天两次部署来进行 DevOps 和持续交付工作,公司为其感到自豪。

在了解了混沌工程和安全实验方面的东西后,该公司的开发团队希望能确定,在一个连续不断的基础上,他们的安全系统对真实世界事件的有效性和快速恢复性怎么样。与此同时,确保他们不会把安全控件不能检测到的新问题引入到系统中。

该团队希望能小规模地通过评估端口安全和防火墙设置来让他们能够检测、阻止和警告他们 EC2 安全组上端口设置的错误配置更改。

  • 该团队首先对他们正常状态下的假设进行总结。
  • 在 EC2 实例里为端口安全进行一个假设。
  • 为未认证的端口改变实验选择和配置 YAML 文件。
  • 该配置会从已选择的目标中随机指定对象,同时端口的范围和数量也会被改变。
  • 团队还会设置进行实验的时间并缩小爆破攻击的范围,来确保对业务的影响最小。
  • 对于第一次测试,团队选择在他们的测试环境中运行实验并运行一个单独的测试。
  • 在真实的 游戏日 Game Day 风格里,团队在预先计划好的两个小时的窗口期内,选择 灾难大师 Master of Disaster 来运行实验。在那段窗口期内,灾难大师会在 EC2 实例安全组中的一个实例上执行这次实验。
  • 一旦游戏日结束,团队就会开始进行一个彻底的、免于指责的事后练习。它的重点在于针对稳定状态和原始假设的实验结果。问题会类似于下面这些:

事后验证问题

  • 防火墙是否检测到未经授权的端口更改?
  • 如果更改被检测到,更改是否会被阻止?
  • 防火墙是否会将有用的日志信息记录到日志聚合工具中?
  • SIEM 是否会对未经授权的更改发出警告?
  • 如果防火墙没有检测到未经授权的更改,那么配置的管理工具是否发现了这次更改?
  • 配置管理工具是否向日志聚合工具报告了完善的信息?
  • SIEM 最后是否进行了关联报警?
  • 如果 SIEM 发出了警报,安全运营中心是否能收到这个警报?
  • 获得警报的 SOC 分析师是否能对警报采取措施,还是缺少必要的信息?
  • 如果 SOC 确定警报是真实的,那么安全事件响应是否能简单地从数据中进行分类活动?

我们系统中对失败的承认和预期已经开始揭示我们对系统工作的假设。我们的使命是利用我们所学到的,并更加广泛地应用它。以此来真正主动地解决安全问题,来超越当前传统主流的被动处理问题的安全模型。

随着我们继续在这个新领域内进行探索,我们一定会发布我们的研究成果。如果您有兴趣想了解更多有关研究的信息或是想参与进来,请随时联系 Aaron Rinehart 或者 Grayson Brewer。

特别感谢 Samuel Roden 对本文提供的见解和想法。


via: https://opensource.com/article/18/4/new-approach-security-instrumentation

作者:Aaron Rinehart 选题:lujun9972 译者:hopefully2333 校对:wxy

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

在命令行中,使用控制运算符为复合命令添加逻辑。

经常会使用一些简单的复合指令,比如说在一个命令行中连接几个命令。这些命令使用分号分隔,表示一个命令结束。为了在一个命令行中创建一系列简单的 shell 命令,只需要使用分号把每一条命令分隔开,就像下面这样:

command1 ; command2 ; command3 ; command4 ;

最后一个分号你可以不用添加,因为当你按下回车键时就表示一个命令的结束,但是为了和其它的保持一致,还是建议加上比较好。

所有的命令执行都没有什么问题 —— 只要没有什么意外发生。但是当出问题时到底发生了什么呢?我们可以预测,并且通过 Bash 中内置的 &&|| 运算符跟踪这些错误。这两个控制运算符提供了一些流控制,可以让我们改变代码执行队列的顺序。分号和换行符也被认为是 Bash 的控制运算符。

&& 运算符意义简单来说就是“如果 command1 执行成功,就接着执行 command2。”如果 command1 因为任何原因执行失败,那么 command2 将不执行。这个语法看下来像这样:

command1 && command2

这样写是允许的,因为每一个命令都会返回一个值(RC)给 shell 来表示这个命令在执行的过程中是否执行成功或者失败。通常,返回值是 0 表示成功,而一个正数值表示不同种类的错误。有一些系统管理工具仅仅返回一个 1 来表示所有的错误,但是也有很多工具使用其它的正数的返回值来表示各种类型错误。

我们可以很容易的使用脚本来检查 shell 变量 $?,可以通过命令列表中的下一个命令,或者可以直接使用系统管理工具检查。我们一起来看这些返回值。运行一个简单的命令然后立即检查它的返回值,这个返回值始终是属于最后一个运行的命令。

[student@studentvm1 ~]$ ll ; echo "RC = $?"
total 284
-rw-rw-r--  1 student student   130 Sep 15 16:21 ascii-program.sh
drwxrwxr-x  2 student student  4096 Nov 10 11:09 bin
<snip>
drwxr-xr-x. 2 student student  4096 Aug 18 10:21 Videos
RC = 0
[student@studentvm1 ~]$

这个返回值是 0,表示这个命令执行成功了。现在尝试使用同样的命令在一些我们没有权限的目录上。

[student@studentvm1 ~]$ ll /root ; echo "RC = $?"
ls: cannot open directory '/root': Permission denied
RC = 2
[student@studentvm1 ~]$

这个返回值的含义可以在 ls 命令的 man 页面 中找到。

现在我们来试试 && 这个控制运算符,因为它也可能会被用在一个命令行程序中。我们将从一个简单的示例开始:创建一个新目录,如果创建成功就在这个目录中创建一个文件。

我们需要一个目录可以创建其它的目录。首先,在你的家目录中创建一个临时的目录用来做测试。

[student@studentvm1 ~]$ cd ; mkdir testdir

~/testdir 中新建一个目录,这也应该是一个空目录,因为是你刚刚创建的,然后创建一个新的空文件在这个新目录中。下面的命令可以做这些事情。

[student@studentvm1 ~]$ mkdir ~/testdir/testdir2 && touch ~/testdir/testdir2/testfile1
[student@studentvm1 ~]$ ll ~/testdir/testdir2/
total 0
-rw-rw-r-- 1 student student 0 Nov 12 14:13 testfile1
[student@studentvm1 ~]$

我们看到一切都运行得很好,因为 testdir 目录是访问且可写的。然后我们改变 testdir 目录的权限,让用户 student 不再具有访问的权限。操作如下:

[student@studentvm1 ~]$ chmod 076 testdir ; ll | grep testdir
d---rwxrw-. 3 student student  4096 Nov 12 14:13 testdir
[student@studentvm1 ~]$

在长列表(ll)命令后面使用 grep 命令来列出 testdir 目录。你可以看到用户 student 不再有 testdir 目录的访问权限。现在我们像之前一样运行同样的命令,但是在 testdir 目录中创建的是一个不同的目录。

[student@studentvm1 ~]$ mkdir ~/testdir/testdir3 && touch ~/testdir/testdir3/testfile1
mkdir: cannot create directory ‘/home/student/testdir/testdir3’: Permission denied
[student@studentvm1 ~]$

尽管我们也同样得到了一个错误的消息,但 && 控制运算符阻止了 touch 命令的运行,因为在创建 testdir3 目录的时候发生了错误。通过这种复合的流控制可以阻止一些错误的发生使事情变乱。但是这样看起来变得稍微复杂了一些。

|| 控制运算符允许添加另一个命令,这个命令在初始程序语句返回值大于 0 时执行。

[student@studentvm1 ~]$ mkdir ~/testdir/testdir3 && touch ~/testdir/testdir3/testfile1 || echo "An error occurred while creating the directory."
mkdir: cannot create directory ‘/home/student/testdir/testdir3’: Permission denied
An error occurred while creating the directory.
[student@studentvm1 ~]$

当我们使用 &&|| 控制运算符时,使用流控制的复合命令的语法格式通常是下面这样的形式。

preceding commands ; command1 && command2 || command3 ; following commands

使用控制运算符的复合命令可以在其它命令之前或者之后,这些和控制运算符流控制有关系,但是不受控制运算符流控制的影响。如果不考虑复合命令的流控制中发生的任何事情那么所有的命令都将执行。

当程序出问题时,这些流控制运算符使得在命令中处理出错和通知我们变得更有效率。我直接在命令行中使用它们,也在脚本中使用。

你可以以 root 用户的身份来删除这个目录和它里面的内容。

[root@studentvm1 ~]# rm -rf /home/student/testdir

你是怎样使用 Bash 控制运算符的呢?在评论区中告诉我们。


via: https://opensource.com/article/18/11/control-operators-bash-shell

作者:David Both 选题:lujun9972 译者:Jamskr 校对:wxy

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

扔掉你的文字编辑器,然后使用这些开源工具在命令行上写作吧。

对于大多数人(尤其是非技术人员),写作意味着在 LibreOffice Writer 或者其他带图形界面的文字处理应用上编辑文本。但是还有许多可行的方法可以让任何人通过文本传递他们的信息,尤其是越来越多的作者选择拥抱纯文本

在使用图形界面写作的世界同样有命令行工具的一席之地。这些命令行工具可以帮助他们进行写作,检查他们的拼写等等 —— 无论是在写一篇文章、博客或者故事;写一个 README 文件;或者准备一份技术文档的时候。

下面是一些在任何写作情况下都有用的命令行工具。

编辑器

没错,你可以在命令行进行真正的写作。我知道一些写作者会使用 NanoVimEmacs、以及 Jove 等编辑器在终端窗口中进行工作。而这些编辑器并非屈指可数。文本编辑器的优势在于它们简单易用以及更专注于文本。非常适合用于编辑任何文本的初稿甚至完成一个漫长而复杂的写作项目。

如果你想在命令行中获得更像文字编辑器的体验,不妨了解一下 WordGrinder。它是一款简单但拥有足够的编写和发布功能的文字编辑器。它支持基本的格式和样式,并且你可以将你的文字以 Markdown、ODT、LaTeX 或者 HTML 等格式导出。

拼写检查

每个写作者在完成他们的工作前至少要(或者说应该要)进行一次拼写检查。为什么呢?在写作的世界里有个永恒的定律,无论你检查了多少次手稿,拼写错误和错字依然会存在。

我曾经详细介绍过我最喜欢的命令行拼写检查工具 GNU Aspell。交互式检测文本文档的 Aspell 不仅能够高亮显示拼写错误还能在拼写错误的上方提供正确的拼写建议。Aspell 在进行拼写检查时同样能够忽略许多语法标记。

另一个够老但仍然有用的代替品是 Ispell。虽然它比 Aspell 稍慢一点,但它们都以相同的方式工作。当你在你的文本文件上工作时,Ispell 将提供正确的建议。Ispell 同样也对英语以外的语言提供了良好的支持。

文章 linter

软件开发人员使用 linter) 来检查他们的代码是否存在错误或者 bug。同样也有用于检查文本样式或语法错误的 linter;而该命令行工具会认为这些错误是样式元素。任何写作者都可以(也应该)使用它,一个文章 linter 对于要求文档风格和样式一致的文档团队项目而言尤其有用。

Proselint 是一款全能的实时检查工具。它会找出行话、大话、不正确日期和时间格式、滥用的术语等等。它也很容易运行并忽略文本中的标记。

Alex 是一个简单但有用的文章 linter。 对明文文本或者格式为 Markdown 或 HTML 的文档使用它。Alex 会对“性别偏好、极端主义、种族相关、宗教,或者文章中其他不平等的措辞”产生警告。如果你想要试试看 Alex,这里有一个在线 demo

其他工具

有时候你找不到一个单词的恰当的同义词。但你不需要去呆板的词库中抓取或者去专门的网站完善你的单词完整。仅仅需要对你想要替换的单词运行 Aiksaurus,然后它就会为你完成这个工作。但是,这个程序最大的缺点是它只支持英语。

即使是只会很少(甚至只有一项)技术技能的写作者都能接受 Markdown 来快速而简单地格式化他们的作品。但是,有时候你也需要将使用 Markdown 格式的文件转换成其他格式。这就是 Pandoc 的用武之地。你可以用它来将你的文档转换成 HTML、Word、LibreOffice Writer、LaTeX、EPUB 以及其他格式。你甚至可以用 Pandoc 来生成书籍和研究论文

你有最喜欢的命令行写作工具吗?在社区发表评论分享它吧。


via: https://opensource.com/article/18/11/command-line-tools-writers

作者:Scott Nesbitt 选题:lujun9972 译者:LazyWolfLin 校对:wxy

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

对于许多数据科学家来说,数据操作从始至终就是 Pandas 或 Tidyverse。从理论上讲,这样做没有任何问题。毕竟,这就是这些工具存在的原因。然而,对于像分隔符转换这样的简单任务,这些工具是大材小用了。

立志掌握命令行应该在每个开发人员的学习清单上,特别是数据科学家。学习 shell 的来龙去脉将无可否认地提高你的生产力。除此之外,命令行还是计算领域的一个重要历史课程。例如,awk —— 一种数据驱动的脚本语言。1977 年,在 Brain Kernighan(即传奇的 K&R 书中 K)的帮助下,awk 首次出现。今天,大约五十年过去了,awk 仍然活跃在每年新出版的书里面。因此,可以安全地假设对命令行魔法的付出不会很快贬值。

我们将涵盖什么

  • ICONV
  • HEAD
  • TR
  • WC
  • SPLIT
  • SORT & UNIQ
  • CUT
  • PASTE
  • JOIN
  • GREP
  • SED
  • AWK

ICONV

文件编码可能会很棘手。现在大部分文件都是 UTF-8 编码的。要了解 UTF-8 背后的一些魔力,请查看这个出色的视频。尽管如此,有时我们收到的文件不是这种编码。这可能引起对改变编码模式的一些胡乱尝试。这里,iconv 是一个拯救者。iconv 是一个简单的程序,它将获取采用一种编码的文本并输出采用另一种编码的文本。

# Converting -f (from) latin1 (ISO-8859-1)
# -t (to) standard UTF_8

iconv -f ISO-8859-1 -t UTF-8 < input.txt > output.txt

实用选项:

  • iconv -l 列出所有已知编码
  • iconv -c 默默丢弃无法转换的字符

HEAD

如果你是一个 Pandas 重度用户,那么会很熟悉 head。通常在处理新数据时,我们想做的第一件事就是了解其内容。这就得启动 Pandas,读取数据然后调用 df.head() —— 要说这有点费劲。没有任何选项的 head 将打印出文件的前 10 行。head 的真正力量在于干净利落的测试操作。例如,如果我们想将文件的分隔符从逗号更改为管道。一个快速测试将是:head mydata.csv | sed 's/,/|/g'

# Prints out first 10 lines
head filename.csv

# Print first 3 lines
head -n 3 filename.csv

实用选项:

  • head -n 打印特定行数
  • head -c 打印特定字节数

TR

tr 类似于翻译。这个功能强大的实用程序是文件基础清理的主力。理想的用例是替换文件中的分隔符。

# Converting a tab delimited file into commas
cat tab_delimited.txt | tr "\t" "," comma_delimited.csv

tr 另一个功能是你可以用内建 [:class:] 变量(POSIX 字符类)发挥威力。这些包括了:

  • [:alnum:] 所有字母和数字
  • [:alpha:] 所有字母
  • [:blank:] 所有水平空白
  • [:cntrl:] 所有控制字符
  • [:digit:] 所有数字
  • [:graph:] 所有可打印字符,但不包括空格
  • [:lower:] 所有小写字母
  • [:print:] 所有可打印字符,包括空格
  • [:punct:] 所有标点符号
  • [:space:] 所有水平或垂直空白
  • [:upper:] 所有大写字母
  • [:xdigit:] 所有 16 进制数字

你可以将这些连接在一起以组成强大的程序。以下是一个基本的字数统计程序,可用于检查 README 是否被滥用。

cat README.md | tr "[:punct:][:space:]" "\n" | tr "[:upper:]" "[:lower:]" | grep . | sort | uniq -c | sort -nr

另一个使用基本正则表达式的例子:

# Converting all upper case letters to lower case
cat filename.csv | tr '[A-Z]' '[a-z]'

实用选项:

  • tr -d 删除字符
  • tr -s 压缩字符
  • \b 退格
  • \f 换页
  • \v 垂直制表符
  • \NNN 八进制字符

WC

单词计数。它的价值主要来自其 -l 选项,它会给你提供行数。

# Will return number of lines in CSV
wc -l gigantic_comma.csv

这个工具可以方便地确认各种命令的输出。所以,如果我们在转换文件中的分隔符之后运行 wc -l,我们会期待总行数是一样的,如果不一致,我们就知道有地方出错了。

实用选项:

  • wc -c 打印字节数
  • wc -m 打印字符数
  • wc -L 打印最长行的长度
  • wc -w 打印单词数量

SPLIT

文件大小的范围可以很广。对于有的任务,拆分文件或许是有好处的,所以使用 split 吧。split 的基本语法是:

# We will split our CSV into new_filename every 500 lines
split -l 500 filename.csv new_filename_
# filename.csv
# ls output
# new_filename_aaa
# new_filename_aab
# new_filename_aa

它有两个奇怪的地方是命名约定和缺少文件扩展名。后缀约定可以通过 -d 标志变为数字。要添加文件扩展名,你需要运行以下 find 命令。它将通过附加 .csv 扩展名来更改当前目录中所有文件的名称,所以小心了。

find . -type f -exec mv '{}' '{}'.csv \;
# ls output
# filename.csv.csv
# new_filename_aaa.csv
# new_filename_aab.csv
# new_filename_aac.csv

实用选项:

  • split -b N 按特定字节大小分割
  • split -a N 生成长度为 N 的后缀
  • split -x 使用十六进制后缀

SORT & UNIQ

上面两个命令很明显:它们的作用就是字面意思。这两者结合起来可以提供最强大的冲击 (例如,唯一单词的数量)。这是由于 uniq 只作用于重复的相邻行。这也是在输出前进行 sort 的原因。一个有趣的事情是 sort -u 会达到和典型的 sort file.txt | uniq 模式一样的结果。

sort 对数据科学家来说确实具有潜在的有用能力:能够根据特定列对整个 CSV 进行排序。

# Sorting a CSV file by the second column alphabetically
sort -t"," -k2,2 filename.csv

# Numerically
sort -t"," -k2n,2 filename.csv

# Reverse order
sort -t"," -k2nr,2 filename.csv

这里的 -t 选项将逗号指定为分隔符,通常假设分隔符是空格或制表符。此外,-k 选项是为了确定我们的键。这里的语法是 -km,nm 作为开始列,n 作为结束列。

实用选项:

  • sort -f 忽略大小写
  • sort -r 反向排序
  • sort -R 乱序
  • uniq -c 统计出现次数
  • uniq -d 只打印重复行

CUT

cut 用于删除列。作为演示,如果我们只想删除第一和第三列。

cut -d, -f 1,3 filename.csv

要选择除了第一行外的所有行。

cut -d, -f 2- filename.csv

结合其他命令,将 cut 用作过滤器。

# Print first 10 lines of column 1 and 3, where "some_string_value" is present
head filename.csv | grep "some_string_value" | cut -d, -f 1,3

查出第二列中唯一值的数量。

cat filename.csv | cut -d, -f 2 | sort | uniq | wc -l

# Count occurences of unique values, limiting to first 10 results
cat filename.csv | cut -d, -f 2 | sort | uniq -c | head

PASTE

paste 是一个带有趣味性功能的特定命令。如果你有两个需要合并的文件,并且它们已经排序好了,paste 帮你解决了接下来的步骤。

# names.txt
adam
john
zach

# jobs.txt
lawyer
youtuber
developer

# Join the two into a CSV
paste -d ',' names.txt jobs.txt > person_data.txt

# Output
adam,lawyer
john,youtuber
zach,developer

更多 SQL 式变种,见下文。

JOIN

join 是一个简单的、 准切向的 quasi-tangential SQL。最大的区别是 join 将返回所有列以及只能在一个字段上匹配。默认情况下,join 将尝试使用第一列作为匹配键。为了获得不同结果,必须使用以下语法:

# Join the first file (-1) by the second column
# and the second file (-2) by the first
join -t "," -1 2 -2 1 first_file.txt second_file.txt

标准的 join 是内连接。然而,外连接通过 -a 选项也是可行的。另一个值得一提的技巧是 -q 标志,如果发现有缺失的字段,可用于替换值。

# Outer join, replace blanks with NULL in columns 1 and 2
# -o which fields to substitute - 0 is key, 1.1 is first column, etc...
join -t"," -1 2 -a 1 -a2 -e ' NULL' -o '0,1.1,2.2' first_file.txt second_file.txt

它不是最用户友好的命令,而是绝望时刻的绝望措施。

实用选项:

  • join -a 打印不可配对的行
  • join -e 替换丢失的输入字段
  • join -j 相当于 -1 FIELD -2 FIELD

GREP

grep 用正则表达式全局搜索并且打印 Global search for a Regular Expression and Print ,可能是最有名的命令,并且名副其实。grep 很强大,特别适合在大型代码库中查找。在数据科学的王国里,它充当其他命令的提炼机制。虽然它的标准用途也很有价值。

# Recursively search and list all files in directory containing 'word'

grep -lr 'word' .

# List number of files containing word

grep -lr 'word' . | wc -l

计算包含单词或模式的总行数。

grep -c 'some_value' filename.csv

# Same thing, but in all files in current directory by file name

grep -c 'some_value' *

对多个值使用“或”运算符: \|

grep "first_value\|second_value" filename.csv

实用选项:

  • alias grep="grep --color=auto" 使 grep 色彩丰富
  • grep -E 使用扩展正则表达式
  • grep -w 只匹配整个单词
  • grep -l 打印匹配的文件名
  • grep -v 非匹配

大人物们

sedawk 是本文中最强大的两个命令。为简洁起见,我不打算详细讨论这两个命令。相反,我将介绍各种能证明其令人印象深刻的力量的命令。如果你想了解更多,这儿就有一本书是关于它们的。

SED

sed 本质上是一个流编辑器。它擅长替换,但也可以用于所有输出重构。

最基本的 sed 命令由 s/old/new/g 组成。它的意思是搜索 old,全局替换为 new。 如果没有 /g,我们的命令将在 old 第一次出现后终止。

为了快速了解它的功能,我们可以深入了解一个例子。 在以下情景中,你已有以下文件:

balance,name
$1,000,john
$2,000,jack

我们可能想要做的第一件事是删除美元符号。-i 标志表示原位。'' 表示零长度文件扩展名,从而覆盖我们的初始文件。理想情况下,你可以单独测试,然后输出到新文件。

sed -i '' 's/\$//g' data.txt
# balance,name
# 1,000,john
# 2,000,jack

接下来,去除 blance 列的逗号。

sed -i '' 's/\([0-9]\),\([0-9]\)/\1\2/g' data.txt
# balance,name
# 1000,john
# 2000,jack

最后 jack 有一天决定辞职。所以,再见了,我的朋友。

sed -i '' '/jack/d' data.txt
# balance,name
# 1000,john

正如你所看到的,sed 有很多强大的功能,但乐趣并不止于此。

AWK

最好的留在最后。awk 不仅仅是一个简单的命令:它是一个成熟的语言。在本文中涉及的所有内容中,awk 是目前为止最酷的。如果你感兴趣,这里有很多很棒的资源 —— 看 这里这里这里

awk 的常见用例包括:

  • 文字处理
  • 格式化文本报告
  • 执行算术运算
  • 执行字符串操作

awk 可以以最原生的形式并行 grep

awk '/word/' filename.csv

或者更加神奇:将 grepcut 组合起来。在这里,对于所有带我们指定单词 word 的行,awk 打印第三和第四列,用 tab 分隔。-F, 用于指定切分时的列分隔符为逗号。

awk -F, '/word/ { print $3 "\t" $4 }' filename.csv

awk 内置了许多精巧的变量。比如,NF —— 字段数,和 NR —— 记录数。要获取文件中的第 53 条记录:

awk -F, 'NR == 53' filename.csv

更多的花招是其基于一个或多个值进行过滤的能力。下面的第一个示例将打印第一列等于给定字符串的行的行号和列。

awk -F, ' $1 == "string" { print NR, $0 } ' filename.csv

# Filter based off of numerical value in second column
awk -F, ' $2 == 1000 { print NR, $0 } ' filename.csv

多个数值表达式:

# Print line number and columns where column three greater
# than 2005 and column five less than one thousand

awk -F, ' $3 >= 2005 && $5 <= 1000 { print NR, $0 } ' filename.csv

求出第三列的总和:

awk -F, '{ x+=$3 } END { print x }' filename.csv

在第一列等于 something 的那些行,求出第三列值的总和。

awk -F, '$1 == "something" { x+=$3 } END { print x }' filename.csv

获取文件的行列数:

awk -F, 'END { print NF, NR }' filename.csv

# Prettier version
awk -F, 'BEGIN { print "COLUMNS", "ROWS" }; END { print NF, NR }' filename.csv

打印出现了两次的行:

awk -F, '++seen[$0] == 2' filename.csv

删除重复的行:

# Consecutive lines
awk 'a !~ $0; {a=$0}']

# Nonconsecutive lines
awk '! a[$0]++' filename.csv

# More efficient
awk '!($0 in a) {a[$0];print}

使用内置函数 gsub() 替换多个值。

awk '{gsub(/scarlet|ruby|puce/, "red"); print}'

这个 awk 命令将组合多个 CSV 文件,忽略标题,然后在最后附加它。

awk 'FNR==1 && NR!=1{next;}{print}' *.csv > final_file.csv

需要缩小一个庞大的文件? awk 可以在 sed 的帮助下处理它。具体来说,该命令根据行数将一个大文件分成多个较小的文件。这个一行脚本将增加一个扩展名。

sed '1d;$d' filename.csv | awk 'NR%NUMBER_OF_LINES==1{x="filename-"++i".csv";}{print > x}'

# Example: splitting big_data.csv into data_(n).csv every 100,000 lines
sed '1d;$d' big_data.csv | awk 'NR%100000==1{x="data_"++i".csv";}{print > x}'

结语

命令行拥有无穷无尽的力量。本文中介绍的命令足以将你从一无所知提升到英雄人物。除了涵盖的内容之外,还有许多实用程序可以考虑用于日常数据操作。Csvkitxsv 还有 q 是需要记住的三个。如果你希望更深入地了解命令行数据科学,查看这本书。它也可以免费在线获得!


via: http://kadekillary.work/post/cli-4-ds/

作者:Kade Killary 选题:lujun9972 译者:GraveAccent 校对:wxy

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

透明和包容性的项目要求可以降低您的失败率。 以下是如何协作收集它们。

众所周知,明确、简洁和可衡量的需求会带来更多成功的项目。一项麦肯锡与牛津大学的关于大型项目的研究表明:“平均而言,大型 IT 项目超出预算 45%,时间每推移 7%,价值就比预期低 56% 。”该研究还表明,造成这种失败的一些原因是“模糊的业务目标,不同步的利益相关者以及过度的返工。”

业务分析师经常发现自己通过持续对话来构建这些需求。为此,他们必须吸引多个利益相关方,并确保参与者提供明确的业务目标。这样可以减少返工,提高更多项目的成功率。

他们可以用开放和包容的方式做到这一点。

成功的框架

提高项目成功率的一个工具是开放决策框架。开放决策框架是一种资源,可以帮助用户在拥抱开放原则的组织中做出更有效的决策。该框架强调三个主要原则:透明、包容、以客户为中心。

透明。很多时候,开发人员和产品设计人员都认为他们知道利益相关者如何使用特定工具或软件。但这些假设往往是不正确的,并导致对利益相关者实际需求的误解。开发人员和企业主讨论时实行透明势在必行。开发团队不仅需要了解一些好的情景,还需要了解利益相关方面对某些工具或流程所面临的挑战。提出诸如以下问题:“必须手动完成哪些步骤?”以及“这个工具是否按预期运行?”这提供了对问题的共同理解和讨论的基准。

包容。对于业务分析师来说,在收集需求时观察肢体语言和视觉暗示非常重要。如果有人双臂交叉或睁着眼睛坐着,那么这清楚地表明他们感觉没被聆听。业务分析师必须鼓励那些不被聆听的人公开交流,并给他们机会被聆听。在开始会议之前,制定基本规则,使所有人都能发表意见并分享他们的想法。聆听提供的反馈,并在收到反馈时礼貌地回复。多样化的意见和协作解决问题将为会议带来令人兴奋的想法。

以顾客为中心。以客户为中心的第一步是识别客户。谁从这种变化、更新或开发中受益?在项目早期,进行利益相关者映射,以帮助确定关键利益相关者,他们在项目中的角色以及他们适应大局的方式。让合适的客户参与并确保满足他们的需求将会确定更成功的要求,进行更现实(现实)的测试,并最终成功交付。

当你的需求会议透明、包容和以客户为中心时,你将收集更好的需求。当你使用开放决策框架来进行会议时,参与者会感觉有更多参与与授权,他们会提供更准确和完整的需求。换一种说法:

透明+包容+以客户为中心=更好的需求=成功的项目


via: https://opensource.com/open-organization/18/2/constructing-project-requirements

作者:Tracy Buckner 译者:geekpi 校对:wxy

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