为什么不在perl中使用awk?

时间:2014-07-13 05:16:28

标签: regex perl awk sed

可能这个问题多次被问到能否在你的perl脚本中加入awk one liner。但是这些问题对于以下问题过于具体:

  1. 提供了一种不同的方法作为建议或
  2. 现有代码中的语法已纠正或
  3. 大多数时间 - >使用perl提供了解决方案,因为专家们赞成使用awk或perl,因为他们都做同样的工作。是。也许。但我认为awk是针对特定问题而设计的,这些问题可以用比perl更好的方法解决。
  4. 示例:我的输出为ls -lart,第9列为文件名。我可以在awk中轻松地做到ls -lart|awk '{print $9}'。同样的事情当然可以使用perl使用readdir()来完成。但是在perl中提取第8列或第7列并不容易?如果我必须将数据管道提取到awk将其传输到sed等,事情会变得更糟。

    另一个例子: 我有一个特定的DIR,它有许多格式的文件,如:

    ABC_9090_DEF_10-22-30_13-07-2014.temp
    

    注意date_time.temp标记部分。此格式为 ABC_4digits_DEF_hours-minutes-seconds_day-month-year

    我想只看到刚刚创建的新文件(比如说从现在起5分钟之前)。使用awk / sed的方法是(伪代码,让我知道你是否需要我复制实际的一个班轮):

    1. ls -lart|awk '{print $9}'|
    2. egrep提取10-22-30_13-07-2014
    3. 使用sed替换_ with - | awk重新排列以具有YEARMONTHDAYHOURSMINUTESSECONDS格式的数字。
    4. 再次使用awk比较这个数字,使用if($ 1> $ mynum)对变量(假设有一个代表TODAYS TIME的相同格式的数字--5分钟)
    5. 问题: 但由于某种原因(其他复杂性)我想用perl写它,我发现if条件 if($ 1> $ mynum)在我使用系统命令在perl中使用它时会抛出错误。它说使用'>'的语法错误即使使用单引号,双引号,也没有引号。

      有人可以告诉我一般情况:

      1. 如果有选择,为什么有人不会在这种情况下使用awk,sed而不是perl?
      2. 在perl中包含awk或sed时应该记住的事情不是特定于这个问题的通用解释(希望也能解决这个特定的问题。

1 个答案:

答案 0 :(得分:6)

  

如果有选择,为什么有人不会在这种情况下使用awk,sed而不是perl?

如果您喜欢这个想法:

  • 从perl
  • 分叉shell
  • 在一个shell里面
  • 再次分叉两个进程(ls& awk)只会打印第9列

随时可以。这对我来说听起来很糟糕,但你知道:你的里程......

  

在perl中包含awk或sed时应该记住的事情不是特定于这个问题的通用解释(希望也应该解决这个特定的问题:))

要记住的通用事项:

  • 转义$variables的规则 - 如$9可解释的内容:
    • 由perl本身(例如$9可以是存储正则表达式捕获的perl变量)
    • 分叉shell的
    • (例如$9可以是保持第9个位置arg的shell变量)
    • awk(这意味着第9列)
  • 知道如何处理系统错误代码
  • 主要是 - 任何编程任务至少需要知道所用编程语言的基础知识。 (这就像我的英语 - 它很糟糕,但写得很好,但是很好):)。

举个例子:ls -lart|awk '{print $9}是你能做的最糟糕的事情之一。

想象:

  • 如果您的文件名称为:this is my file.txt
  • 什么会打印ls -lart|awk '{print $9}

猜对了,只打印this。当然,这是错误的。解析文件名是什么 来自stdin总是很糟糕(除非你有NULL终止的文件名),因为文件名可以包含空格 - 不仅是spaces,还有tabnewline个字符。

到第二个例子:

  • 而不是在链(管道)中运行4个程序,您可以使用find来实现所需:print only new files modified in the last 5 min
  • 使用perl你可以使用perl模块:
    • File::Find - 可以执行find命令所做的任何事情以及更多
    • File::Find::Rule - File :: Find
    • 的替代界面
    • 和许多其他模块:来自File::Find家庭
    • see
    • 但您可以使用例如Path::TinyClass::Path或类似的模块
    • 等...