2行を含む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」を含む行が表示されますが、3番目の単語を出力として抽出したいと思います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
2つawk
のコマンドは同じですが、異なる式を照会するために異なるパラメータが提供されます。コマンドラインの変数に割り当てられたawk
文字列はq
拡張正規表現として使用され、指定されたファイルのすべての行と一致します。式が 1 行に一致すると、最後の 2 番目のフィールドが印刷されます。これは、特殊変数NF
(現在行のフィールド番号)を使用して2番目のフィールド()のフィールド番号を計算することによって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と多少似ていますが、今回はgrepに前後のすべての項目を(?<=tables/)
返すように指示するためにこれを追加しました。tabels/
/tl
awk
正規表現を使用したくない場合は、コマンドを使用してこれを実行することもできます。
検索するには、XYZ
次のものを使用できます。
grep "db" abc.txt | awk -F '/' '{ print $1 }'
したがって、この場合、grep
コマンドは行全体を返しますが、awk
区切り文字を使用して行を分割し、/
分割行の最初の部分を返します。
検索するには、table_name
次の操作を行います。
grep "tl" abc.txt | awk -F '/' '{ print $3 }'
これは最初のコマンドと非常によく似ていますが、この場合は文の3番目の部分が必要です。