我的文件夹中有很多 .gz 文件
/a/b/c1.gz
/a/b/c2.gz
/a/b/c3.gz
等等。
有些文件有一个管道分隔符,有些有两个、三个和四个等等,如下所示:
xyz|abc
xyz|abc|wty
xyz|abc|wty|asd
等等。
如何找到所有具有两个管道分隔符、三个分隔符等的文件?
答案1
假设在任何给定文件中,|
- 分隔的列数是恒定的,那么检查文件的第一行就足以确定其中的列数。
以下将对名为 的文件执行此操作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
答案2
让我们创建三个测试文件:
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
答案3
您可以通过管道将文件名传递给 awk 并查找每个文件中 |- 的数量。例如: echo 'A|B|C' |awk -F\| '{打印 NF-1}'