通过查找命令

时间:2017-06-02 06:48:31

标签: shell unix

我想对find命令返回的zip文件使用awk命令,并将zip文件中的一些特定列转储到与zip文件具有相同层次结构的新文件中。

例如,我的结构如下:

/2017/05/25/GAURshvol20170525.txt.zip
/2017/05/26/GAURsh20170526.txt.zip
/2017/05/26/GUPTsh20170526.txt.zip
/2017/05/26/GUPTshvol20170526.txt.zip
/2017/05/26/GAURshvol20170526.txt.zip
/2017/05/30/GAURshvol20170530.txt.zip
/2017/05/30/GAURsh20170530.txt.zip
/2017/05/30/GUPTsh20170530.txt.zip
/2017/05/30/GUPTshvol20170530.txt.zip
/2017/05/31/GAURsh20170531.txt.zip
/2017/05/31/GUPTsh20170531.txt.zip
/2017/05/31/GUPTshvol20170531.txt.zip

在zip文件中的每个文件中,我都有如下数据:

20170601|A|69636|122548|Z
20170601|AA|67544|128724|Z
20170601|AAAP|453|1306|Z
20170601|AAC|5840|8962|Z
20170601|AADR|1925|1925|Z
20170601|AAL|289708|344209|Z
20170601|AAMC|10|15|Z
20170601|AAME|100|200|Z
20170601|AAN|44851|72461|Z
20170601|AAOI|42836|82801|Z
20170601|AAON|3417|4127|Z
20170601|AAP|71212|85414|Z
20170601|AAPL|528135|1213451|Z
20170601|AAT|7742|10104|Z
20170601|AAU|2200|2700|Z
20170601|AAV|2746|6797|Z
20170601|AAWW|4662|7298|Z
20170601|AAXJ|54464|57764|Z
20170601|AAXN|45497|48611|Z

现在,我想从上面获取一些特定的列并将它们转储到具有相同类型层次结构的新目录中的新文件中,就像我将数据转储到目录abcd中一样,那么层次结构应该像

gaur/2017/05/25/GAURshvol20170525.txt
gaur/2017/05/26/GAURsh20170526.txt
gaur/2017/05/26/GUPTsh20170526.txt
gaur/2017/05/26/GUPTshvol20170526.txt
gaur/2017/05/26/GAURshvol20170526.txt
gaur/2017/05/30/GAURshvol20170530.txt
gaur/2017/05/30/GAURsh20170530.txt
gaur/2017/05/30/GUPTsh20170530.txt
gaur/2017/05/30/GUPTshvol20170530.txt
gaur/2017/05/31/GAURsh20170531.txt
gaur/2017/05/31/GUPTsh20170531.txt
gaur/2017/05/31/GUPTshvol20170531.txt

我尝试了以下命令,(目前我的pwd是2017年和gaur的父目录):

find -name 'GAUR*.zip' -exec awk -F"|" '{print $2,$3 > (FILENAME "-new")}' {} +

导致无限等待。我更有兴趣在查找部分使用正则表达式,如果任何人可以取悦,为我使用。

find . -regex '.^GAUR*\.\(zip\|\)'

但失败了。

2 个答案:

答案 0 :(得分:1)

以递归方式查找当前目录中的所有文件,以GAUR开头,以.zip结尾,逐行读取,创建目录,解压缩文件,并将输出重定向到awk print 2.和3. col到当前目录中的文件/ gaur /原始文件路径(sed从文件名中删除.zip扩展名),不带.zip结尾。

find -name 'GAUR*.zip' | while read line ; do mkdir -p gaur/$(dirname $line) && unzip -p $line | awk -F"|" '{ print $2","$3 }' > ./gaur/$(echo $line | sed 's/.zip$//g') ; done

您必须首先解压缩文件,然后才能在文件上运行awk。所以我做了这个丑陋的衬垫来做到这一点。但是很难修改,所以我会使用常规shell脚本。

答案 1 :(得分:1)

这没有一个简单的解决方案,因为您需要awk中文件的文件名和内容。问题是您无法在-exec中使用管道。

没有其他文件的解决方案将调用-exec sh -c 'zcat | awk',但是你将在awk部分中进行大量的转义工作。

但最好的解决方案是创建一个这样的脚本:

script.sh:

#!/bin/sh
for i in "$@" ; do
    mkdir -p gaur/"$(dirname "$i")"
    filename="$(echo gaur/"$i" | sed 's/\.zip$//')"
    zcat "$i" | awk -F'|' -v filename="$filename" '{print $2,$3 > filename}'
done

然后只需致电:

find 2017 -regex '.*/GAUR.*\.zip' -exec ./script.sh {} +