【问题标题】:how do I select only shell scripts from a collection of files如何从文件集合中仅选择 shell 脚本
【发布时间】:2013-06-08 02:15:35
【问题描述】:

我想找到我所有的 bash 脚本(我现在已经积累了很多)并通过bash -n 自动运行它们。

有什么快速的方法来做到这一点?我想让grep 只匹配第一个非空行以#!/bin/sh#!/usr/bin/env sh#!/usr/bin/env bash#!/bin/bash 开头的文件...

一个有用的答案当然是类似于

for file in *; do 
    if head -n 5 $file | grep "#!.*sh$" > /dev/null; then
        bash -n $file
    fi
done

但为了“正确性”,我如何合理地在 仅第一个非空白(或非空白) 行上执行我的 grep?

【问题讨论】:

  • file 命令比 grep 更能告诉你是否是 shell 脚本。我可以告诉你,bash -n 可以对一组脚本提供的有限检查非常弱,以至于毫无用处;大多数解释型语言都很难(不可能?)通过静态分析来提供很多东西。
  • 好吧。我会尽我所能,如果它知道明显的语法错误,这对我很有帮助。我会调查file,谢谢
  • 没有理由寻找“第一个非空行”。 #!(“shebang”)必须是文件第一行的第一个字符。因此,查看文件的第一行就足够了。
  • @robmayoff 啊,谢谢。不知道那个。但既然我想知道怎么做,我必须知道。
  • @msw 您应该发布file 命令的建议作为答案。

标签: bash shell unix grep


【解决方案1】:

使用查找:

     find . -type f -exec grep -e "^#\!\/bin\/.*sh$" {} +

【讨论】:

  • @jaypal,确定吗?我认为+ 会更有效率。 + 会将每个文件(尽可能多地)传递给grep\; 将为每个单独的文件调用 grep
  • 是的,+ 是高效的,因为 OP 提到他有很多文件,使用 + 将分批传递文件名,而 {} \; 将一次传递一个文件。我对你的答案投了赞成票! :)
【解决方案2】:

GNU awk

awk '
FNR==1 && $0~/#!\/bin\/sh|#!\/usr\/bin\/env sh|#!\/usr\/bin\/env bash|#!\/bin\/bash/ { 
    print FILENAME " is shell script";
}
FNR>1 {
    nextfile
}' *
  • 您可以使用上面的regex 并将其缩减为仅#!
  • FNR==1regex 将确保检查第一行的 she-bang 行。
  • nextfile 将确保不会在第一行之外查看任何文件。
  • print 如果只是为了记录。
  • FILENAME 将打印正在检查的文件的名称。
  • * 将覆盖工作目录下的所有文件。

【讨论】:

  • @StevenLu awk 唯一可怕的是名字。 :)
  • nextfile 仅在第一行匹配时被调用。
猜你喜欢
  • 1970-01-01
  • 2013-02-02
  • 1970-01-01
  • 2022-09-30
  • 2012-08-20
  • 1970-01-01
  • 2021-09-06
  • 2018-05-19
  • 1970-01-01
相关资源
最近更新 更多