在linux中以“/”符号结尾之前从txt文件中提取第一个单词,其中txt行中包含“db”单词

在linux中以“/”符号结尾之前从txt文件中提取第一个单词,其中txt行中包含“db”单词

我有 abc.txt 文件,其中包含两行。我想提取包含db特定行中的单词的行中的第一个单词。

abc.txt:

XYZ/db_abc.sql
ijkl/tables/table_name/tl_abc.sql

当我尝试 grep 时,grep "db" abc.txt我得到包含“db”的行,但我想提取第一个单词XYZ作为输出。

输出:

$ grep "db" abc.txt
XYZ/db_abc.sql

预期输出:

XYZ

同样,当我尝试 grep 时,grep "tl" abc.txt我得到包含“tl”的行,但我想提取第三个单词table_name作为输出。

输出:

$ grep "tl" abc.txt
ijkl/tables/table_name/tl_abc.sql

预期输出:

table_name

答案1

$ awk -F / -v q=db '$0 ~ q { print $(NF-1) }' file
XYZ
$ awk -F / -v q=tl '$0 ~ q { print $(NF-1) }' file
table_name

这两个awk命令是相同的,但给出了不同的参数来查询不同的表达式。在命令行上分配给awk变量的任何字符串都q将用作扩展正则表达式,并将与给定文件中的每一行进行匹配。当表达式与一行匹配时,将打印从末尾算起的第二个字段。这是通过使用特殊变量NF(当前行的字段数)来计算倒数第二个字段的字段号 ( NF-1) 来完成的。该实用程序通过斜杠分隔字段(如使用 所示-F /)。

其变体可确保查询模式仅在最后一个字段中匹配:

awk -F / -v q=tl '$NF ~ q { print $(NF-1) }' file

另外确保我们只关心以 结尾的行.sql

awk -F / -v q=tl '/\.sql$/ && $NF ~ q { print $(NF-1) }' file

答案2

它会返回整行,因为 grep 默认情况下是这样工作的。要提取句子的某个部分,我建议您使用正则表达式。

要提取XYZ句子,您可以使用如下构建的正则表达式:

grep -oP ".*(?=/db) abc.txt"

-o是只返回与模式匹配的行。

-P是使用 来搜索模式Perl Regex

.*搜索除以下字符之外的任何字符\n

(?=/db)会说寻找匹配字符串后面的所有内容,/db但一旦到达字符串本身就停止匹配。意思是,不包括/db以及除此之外的任何东西。

类似地,为了寻找,table_name我们需要应用类似的方法。我们可以像这样使用正则表达式:

grep -oP "(?<=tables/).*(?=/tl) abc.txt"

这与上一个 grep 有点相似,但这次我们添加了(?<=tables/) 它,告诉 grep 返回 之前tabels/和之后的任何内容/tl

awk如果您不想使用正则表达式,我们也可以通过使用命令来完成此操作。

要检索XYZ您可以使用:

grep "db" abc.txt | awk -F '/' '{ print $1 }'

因此,在这种情况下,该grep命令将返回整行,但我们使用awk分隔符来分割该行/,并返回分割行的第一部分。

要检索table_name我们可以这样做:

grep "tl" abc.txt | awk -F '/' '{ print $3 }'

这与第一个命令非常相似,但在这种情况下我们需要句子的第三部分。

相关内容