Linux
zgrep 用於一堆 gz 文件中的多個管道符號
我的文件夾中有很多 .gz 文件
/a/b/c1.gz /a/b/c2.gz /a/b/c3.gz
等等。
一些文件有一個管道分隔符,一些文件有兩個、三個和四個等等,以這種方式:
xyz|abc xyz|abc|wty xyz|abc|wty|asd
等等。
如何找到總體上具有兩個管道定界符、總體上具有三個定界符等的所有文件?
讓我們創建三個測試文件:
echo 'xyz|abc' > c1 echo 'xyz|abc|wty' > c2 echo 'xyz|abc|wty|asd' > c3 gzip c*
一行中包含一個管道的文件:
$ zgrep '^[^|]*|[^|]*$' *.gz c1.gz:xyz|abc
對於任何其他數字(包括一行中的一個管道),您可以使用以下模式:
兩條管道在一條線上:
$ zgrep -E '^([^|]*\|){2}[^|]*$' *.gz c2.gz:xyz|abc|wty
三個管道在一條線上:
$ zgrep -E '^([^|]*\|){3}[^|]*$' *.gz c3.gz:xyz|abc|wty|asd
兩根或三根管子排成一行:
$ zgrep -E '^([^|]*\|){2,3}[^|]*$' *.gz c2.gz:xyz|abc|wty c3.gz:xyz|abc|wty|asd
最大限度。三個管道排成一行:
$ zgrep -E '^([^|]*\|){,3}[^|]*$' *.gz c1.gz:xyz|abc c2.gz:xyz|abc|wty c3.gz:xyz|abc|wty|asd
如果您只需要文件名,請添加選項
-l
,即zgrep -lE ...
我的
zgrep
版本不支持遞歸-r
選項。您可以使用
find
遞歸搜尋並zgrep
在結果上執行:$ find . -type f -name '*.gz' -exec zgrep -lE '^([^|]*\|){3}[^|]*$' {} \; ./c3.gz
假設在任何給定文件中, -分隔的
|
列數是恆定的,那麼檢查文件的第一行以確定其中的列數就足夠了。以下將對名為的文件執行此操作
name.gz
:gzip -dc name.gz | awk -F '|' -v name="name.gz" '{ print NF, name } { exit }'
因此,通過一個簡單的循環,您將能夠輸出列數和文件名,例如,與模式匹配的所有文件
/a/b/c*.gz
:for name in /a/b/c*.gz; do gzip -dc "$name" | awk -F '|' -v name="$name" '{ print NF, name } { exit }' done
如果您只想輸出具有一定數量列的文件的名稱(
n=3
例如),則使用n=3 for name in /a/b/c*.gz; do gzip -dc "$name" | awk -F '|' -v n="$n" -v name="$name" 'NF == n { print name } { exit }' done