sed/awk 参加 'words' 的第一部分

sed/awk to take first part of 'words'

我正在努力学习 sed/awk 并且我计划在以下任务中使用它。我有一个命令可以打印出文件列表(每行可能不止一个),如下所示:

--- /section/1 ---
appname1/detail1/something appname1/detail2/somethingelse another/app/2.0
sillyapp/details/here  bug/2.5
--- /section2/details/here ---
apname2/3.2.5  apname2/3.2.6 apname3/something.0.4/here

我想做两件事:

(1) 使用 sed 仅获取 文件的第一部分(从 ' ' 到 '/'),这样我们就会

--- /section/1 ---
appname1 appname1 another
sillyapp  bug
--- /section2/details/here ---
apname2 apname2 apname3

(2) 使用 awk(我想?)找出每个应用程序被列出的次数,这样我们就可以

appname1: 2
another: 1
sillyapp: 1
bug: 1
apname2: 2
apname3: 1

sed/awk可以用来做这个吗?如果是这样,有人可以详细说明如何完成每一项(为什么有效)?

我将使用带有 -o 的 grep 来仅提取匹配项,并使用 -P 来获取与 perl 兼容的正则表达式:

grep -Po '(^|\s)\K\w+(?=/)' file | sort | uniq -c
  1 another
  2 apname2
  1 apname3
  2 appname1
  1 bug
  1 sillyapp

那个正则表达式是:

(^|\s)  # either the beginning of the line, or a space
\K      # forget about what came before (i.e. don't remember the space)
\w+     # some word characters
(?=/)   # the next character is a slash (look-ahead)

with sed:我不是大师,但我想出了这个:

sed -nr '/^---/d; s/(^| +)([^/]+)[^ ]+/ /g; H; ${x;s/\n//g;s/ $//; s/ /\n/g;p}' file
appname1
appname1
another
sillyapp
bug
apname2
apname2
apname3

也就是

sed -nr '          # -n suppress printing; -r enable extended regular expressions
    /^---/d                      # delete "header" lines
    s/(^| +)([^/]+)[^ ]+/ /g   # extract the words you want, add a trailing space
    H                            # append this transformed line to the hold space
    ${                           # on the last line of input:
        g                        # bring the hold space contents into the pattern space
        s/\n//g                  # remove newlines
        s/ $//                   # remove a trailing space
        s/ /\n/g                 # change spaces into newlines
        p                        # and, finally, print the results
    }
' file

在此之后,添加| sort | uniq -c如上