如何根据搜索返回分割线的全部内容?

时间:2014-08-14 20:00:50

标签: bash awk sed cat

posted previously关于我正在处理的一个小脚本。我终于弄明白了这个问题。现在我遇到了另一个。希望你能提供帮助。

一些设置:我将一个短列表存储为降价文件。

|One Hundred Years of Solitude|Gabriel García Márquez|-|-|-|-|1967|
|Moby-Dick|Herman Melville|-|-|-|-|1851|
|Frankenstein|Mary Shelley|-|-|-|-|1818|
|On the Road|Jack Kerouac|-|-|-|-|1957|
|The Turn of the Screw|Henry James|-|-|-|-|-|

我已经想出了如何通过cat,sed,xargs和awk提供文件。

cat list.md | sed -e 's/^\|//' -e 's/\|$//' -e 's/^ *//' \
-e '/^\:/d' -e '/\'Title'/d' -e '/^\r/d' -e '/^$/d' | xargs -0 echo | \
awk -F '|' '{print "----"} {print "Title:", $1} {print "Author:", $2} \
{print "Date Begun:", $4} {print "Date Finished:", $5}'

该命令返回:

----
Title: One Hundred Years of Solitude
Author: Gabriel García Márquez
Date Begun: -
Date Finished: -
----
Title: Moby-Dick
Author: Herman Melville
Date Begun: -
Date Finished: -
----
Title: Frankenstein
Author: Mary Shelley
Date Begun: -
Date Finished: -
----
Title: On the Road
Author: Jack Kerouac
Date Begun: -
Date Finished: -
----
Title: The Turn of the Screw
Author: Henry James
Date Begun: -
Date Finished: -

我想要做的是将其合并到一个脚本中,我可以使用像“书籍Melville”这样的参数运行,它将运行上述命令,将其输入grep,搜索参数(最好是单词或一个字符串),然后返回整行。如果我输入“书籍Melville”,脚本将返回

----
Title: Moby-Dick
Author: Herman Melville
Date Begun: -
Date Finished: -

目前,如果我输入'书籍Melville',它返回的全部是'作者:Herman Melville'。

很抱歉这篇长篇文章。

用另一个道歉编辑:我忘了提到我在OSX上。

3 个答案:

答案 0 :(得分:2)

我将为您提供两个小awk脚本(由于多个字符awk,将需要GNU RS作为第二个脚本。您可以通过仅使用空格而不是{来使其可移植{1}}并使用----段落模式)。第一个脚本是删除所有混乱并创建数据库文件。

awk

$ cat md.file
|One Hundred Years of Solitude|Gabriel García Márquez|-|-|-|-|1967|
|Moby-Dick|Herman Melville|-|-|-|-|1851|
|Frankenstein|Mary Shelley|-|-|-|-|1818|
|On the Road|Jack Kerouac|-|-|-|-|1957|
|The Turn of the Screw|Henry James|-|-|-|-|-|

现在$ awk -F"[|]" '{ printf "----\nTitle: %s\nAuthor: %s\nDate Begun: %s\nDate Finished: %s\n", $2, $3, $5, $6 }' md.file > database.file 看起来像这样:

database.file

文件准备就绪后,您可以在---- Title: One Hundred Years of Solitude Author: Gabriel García Márquez Date Begun: - Date Finished: - ---- Title: Moby-Dick Author: Herman Melville Date Begun: - Date Finished: - ---- Title: Frankenstein Author: Mary Shelley Date Begun: - Date Finished: - ---- Title: On the Road Author: Jack Kerouac Date Begun: - Date Finished: - ---- Title: The Turn of the Screw Author: Henry James Date Begun: - Date Finished: - 脚本或命令行中使用以下awk脚本,这是您认为合适的方式。

如果您希望从bash文件运行,则可以创建要搜索的bash变量。

bash

如果你希望绕过shell变量,你可以进行正则表达式搜索。

$ look=Melville
$ echo "$look"
Melville
$ awk -v RS="----" -vlook="$look" '$0~look' database.file

Title: Moby-Dick
Author: Herman Melville
Date Begun: -
Date Finished: -
如果您的条件为awk -v RS="----" '/Melville/' database.file

awk会为您打印。这意味着,上述陈述与

完全相同
true

awk -v RS="----" '/Melville/ { print $0 }' database.file

答案 1 :(得分:1)

使用bash:

seek=he
labels=(- Title Author - "Date Begun" "Date Finished")
while IFS='|' read -ra fields; do
    [[ "${fields[*]}" == *"$seek"* ]] || continue
    printf "%s\n" "----"
    for i in 1 2 4 5; do
        printf "%s: %s\n" "${labels[i]}" "${fields[i]}"
    done
done < list.md
----
Title: Frankenstein
Author: Mary Shelley
Date Begun: -
Date Finished: -
----
Title: On the Road
Author: Jack Kerouac
Date Begun: -
Date Finished: -
----
Title: The Turn of the Screw
Author: Henry James
Date Begun: -
Date Finished: -

答案 2 :(得分:0)

使用Awk:

#!/usr/bin/awk -f
BEGIN {
    if (!(ARGC >= 2)) exit
    search = ARGV[1]
    ARGV[1] = "/complete/path/to/list.md"
    FS = "|"
    OFS = "\n"
}
$0 ~ search {
    print "----", "Title: " $2, "Author: " $3, "Date Begun: " $4, "Date Finished: " $5
}

使用真实值更改值"/complete/path/to/list.md"。将其保存在$PATH所涵盖的目录中,例如/usr/local/bin,并将其命名为books。将其权限更改为0755,然后使用books Melv进行测试。

如果您没有以root身份运行,为了更轻松,首先将其保存到script.awk等临时文件,进行一些正确的编辑,然后运行:

sudo install -m 0755 script.awk /usr/local/bin/books

多个关键字

此版本允许多个关键字验证搜索:

#!/usr/bin/awk -f
BEGIN {
    if (!(ARGC >= 2)) exit
    for (i = 1; i < ARGC; ++i) {
        keywords[k++] = ARGV[i]
    }
    ARGV[1] = "/complete/path/to/list.md"
    ARGC = 2
    FS = "|"
    OFS = "\n"
}
$0 ~ keywords[0] {
    for (i = 1; i < k; ++i) {
        if (!($0 ~ keywords[i])) {
            next
        }
    }
    print "----", "Title: " $2, "Author: " $3, "Date Begun: " $4, "Date Finished: " $5
}