【问题标题】:How extract strings between < and > with sed or awk如何使用 sed 或 awk 提取 < 和 > 之间的字符串
【发布时间】:2014-02-08 04:43:03
【问题描述】:

我想提取 之间的所有头文件。我有一个来自 git 存储库的名为 configure.ac 的文件。我想知道这个文件中存在哪些头文件。我想生成一个只有头文件的列表文件。示例:

# _NL_MEASUREMENT_MEASUREMENT is an enum and not a define
AC_MSG_CHECKING([for _NL_MEASUREMENT_MEASUREMENT])
AC_LINK_IFELSE(
  [AC_LANG_PROGRAM(
    [[#include <langinfo.h>]],
    [[char c = *((unsigned char *)  nl_langinfo(_NL_MEASUREMENT_MEASUREMENT));]])],
  [nl_ok=yes],
  [nl_ok=no])
AC_MSG_RESULT($nl_ok)
if test "$nl_ok" = "yes"; then
  AC_DEFINE(HAVE__NL_MEASUREMENT_MEASUREMENT, 1,
        [Define to 1 if _NL_MEASUREMENT_MEASUREMENT is available])
fi

  if test "$ac_cv_header_sys_shm_h" = "yes"; then
    AC_MSG_CHECKING(whether shmctl IPC_RMID allowes subsequent attaches)
    AC_RUN_IFELSE(
      [AC_LANG_SOURCE([[
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    int main()
    {
      int id;
      char *shmaddr;
    id = shmget (IPC_PRIVATE, 4, IPC_CREAT | 0600);
    if (id == -1)
      exit (2);
      shmaddr = shmat (id, 0, 0);
      shmctl (id, IPC_RMID, 0);
      if ((char*) shmat (id, 0, 0) == (char*) -1)
      {
        shmdt (shmaddr);
        exit (1);
      }
      shmdt (shmaddr);
      shmdt (shmaddr);
      exit (0);
    }
      ]])],
      [AC_DEFINE([IPC_RMID_DEFERRED_RELEASE],[1],
                 [Define to 1 if shared memory segments are released deferred.])
       AC_MSG_RESULT(yes)],
      [AC_MSG_RESULT(no)],
      [AC_MSG_RESULT(assuming no)])

    AC_DEFINE(USE_SYSV_SHM, 1, [Define to 1 to use SYSV shared memory])
  else
    shmtype=none
  fi



输出文件必须包含:

langinfo.h
类型.h
ipc.h
shm.h


我试过了:

echo "#include <stdio.h>" | sed -n 's/.*<\(.*\)\>.*/\1/p'
---> stdio.h

cat configure.ac | sed -n 's/.*<\(.*\)\>.*/\1/p' | sort -u > list.txt
---> It doesn't work



我找不到错误。

【问题讨论】:

    标签: bash sed awk


    【解决方案1】:

    这在一定程度上取决于您的 sed 版本。在 Mac OS X 10.9.1 Mavericks (BSD sed) 上,这有效:

    $ sed -n 's/.*\<\(.*\)\>.*/\1/p' data
    langinfo.h
    sys/types.h
    sys/ipc.h
    sys/shm.h
    $
    

    (其中data 是您在问题中引用的configure.ac 的片段)。 OTOH,GNU sed(4.2.2 版)给出(... 被省略了行):

    $  /usr/gnu/bin/sed -n 's/.*\<\(.*\)\>.*/\1/p' data
    a
    _NL_MEASUREMENT_MEASUREMENT
    AC_LINK_IFELSE
    AC_LANG_PROGRAM
    h
    _NL_MEASUREMENT_MEASUREMENT
    yes
    ...
    AC_LANG_SOURCE
    h
    h
    h
    main
    id
    shmaddr
    ...
    else
    shmtype
    fi
    $
    

    将正则表达式更改为:

    $ /usr/gnu/bin/sed -n 's/.*<\(.*\)>.*/\1/p' data
    langinfo.h
    sys/types.h
    sys/ipc.h
    sys/shm.h
    $
    

    与 BSD sed 的输出相同。

    道德:默认情况下,尖括号&lt;&gt; 不是元字符,不需要反斜杠转义。

    当它们被转义时,它们具有特定的含义(词尾或附近)。

    【讨论】:

    • 谢谢。它适用于:cat configure.ac | sed -n 's/.*.*/\1/p' |排序 -u > list.txt
    • 其中一件令人沮丧的事情是人们决定更改sed 支持哪个正则表达式系统的规则,因此现在不同的平台支持不同的变体。这是一个真正的痛苦!而且,更糟糕的是,有时他们使用选项来明确地改变行为(这很好),有时他们似乎默认做不同的事情 - 异想天开,不一致且非常令人沮丧。请注意,sed 本身可以读取文件;如果你写 cat | sed,你会让自己面临 UUOC 的指控——cat 的无用使用。
    • 是的,你是对的。这令人沮丧。我认为 是元字符。 \> 表示:查找开头的字符。规则不统一,不明确。到处都有例外。
    【解决方案2】:
    perl -lne 'print $1 if(/\<(.*?)\>/)' your_file
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-26
      • 1970-01-01
      • 2012-11-03
      • 1970-01-01
      • 1970-01-01
      • 2011-09-16
      相关资源
      最近更新 更多