好的,奥克珀尔-福古鲁。这里有一个类似于这些(Extract specific strings...)和(Using awk to...)的,只是我需要使用从文件A的每一行(销售订单行项目中的PO号)中提取的4-10列中提取的数字,并使用它定位B文件中的所有相关行,并将它们打印到一个新文件中。
文件A(购买订单详细信息)行如下所示:
xxx01234560000000000000000000 yyy zzzz000000
文件B(与POs关联的供应商代码)行如下所示:
00xxxxx01234567890123456789001234567890
文件A中的第4-10列有一个7位的PO编号,这可以在文件B的第7-13列中找到。我需要做的是解析文件A以获得PO号,然后从B文件中创建一个新的子文件,该文件只包含文件B中有文件A中的POs的那些行。所创建的子文件实质上是B文件中有订单的供应商的子集。
我试过几件事,但我真的在为这件事做一条单线。我可以通过定义变量等方法在脚本中解决这个问题,但我很好奇是否有人知道一条巧妙的一行程序可以完成这样的任务。两种参考的方法加在一起应该可以做到,但我还不太明白。
发布于 2014-07-03 19:13:39
这里有一条单线:
egrep -f <(cut -c4-10 A | sed -e 's/^/^.{6}/') B
看起来文件B中的POs实际上是从第8列开始的,而不是从第7列开始的,但正如您在问题中所问的那样,我将正则表达式从第7列开始。
如果在A中存在重复的可能性,在扫描B文件之前将它们清除掉,可以提高效率:
egrep -f <(cut -c4-10 A | sort -u | sed -e 's/^/^.{6}/') B
发布于 2014-07-03 19:07:23
sed 's_^...\(\d\{7\}\).*_/^.\{6\}\1/p_' FIRSTFILE > FILTERLIST
sed -n -f FILTERLIST SECONDFILE > FILTEREDFILE
第一行从第一文件生成sed脚本,而第二行使用该脚本过滤第二行。这也可以合并成一行..。
如果文件不是那么大,你可以做一些类似的事情
awk 'BEGIN { # read the whole FIRSTFILE PO numbers to an array }
substr($0,7,7} in array { print $0 }' SECONDFILE > FILTERED
您可以这样做(但是它会在一行的任何地方找到PO编号)
fgrep -f <(cut -b 4-10 FIRSTFILE) SECONDFILE
发布于 2014-07-03 20:06:24
另一种只使用grep
的方法:
grep -f <(grep -Po '^.{3}\K.{7}' fileA) fileB
解释:
-P
-o
只选择匹配\K
是Perl正向后看https://stackoverflow.com/questions/24560833
复制相似问题