私のフォルダには.gzファイルがたくさんあります。
/a/b/c1.gz
/a/b/c2.gz
/a/b/c3.gz
など。
一部のファイルにはパイプ区切り文字が1つあり、一部のファイルには2つ、3つ、4つなどがあります。
xyz|abc
xyz|abc|wty
xyz|abc|wty|asd
など。
2つのパイプ区切り記号、3つの区切り記号などを含むすべてのファイルを見つける方法は?
答え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
3つのテストファイルを作成しましょう。
echo 'xyz|abc' > c1
echo 'xyz|abc|wty' > c2
echo 'xyz|abc|wty|asd' > c3
gzip c*
1行に1つのパイプを含むファイル:
$ zgrep '^[^|]*|[^|]*$' *.gz
c1.gz:xyz|abc
他の数字(連続したパイプを1つ含む)の場合は、次のパターンを使用できます。
2本のパイプが並んでいます。
$ zgrep -E '^([^|]*\|){2}[^|]*$' *.gz
c2.gz:xyz|abc|wty
3つの連続したパイプ:
$ zgrep -E '^([^|]*\|){3}[^|]*$' *.gz
c3.gz:xyz|abc|wty|asd
連続した2本か3本の管:
$ zgrep -E '^([^|]*\|){2,3}[^|]*$' *.gz
c2.gz:xyz|abc|wty
c3.gz:xyz|abc|wty|asd
最高。 3つの連続したパイプ:
$ 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\| 「{Print NF-1}」