gnu shell命令中基于模式的文件名过滤

时间:2016-12-07 15:36:12

标签: regex bash shell unix awk

假设我有一个包含这些文件的active/目录

active/
foo.bar.abc
foo.bar.xyz
foo.bat.abc

archive/
foo.bat.xyz

我想编写一个命令,只输出active/中的唯一文件名(基于中间项的唯一性)并且与archive/中已有的任何文件不匹配(同样基于该中期项) )。

示例输出:

foo.bar.abc

说明:输出foo.bar.abcfoo.bar.xyz并不重要。自foo.bat.abc

中存在foo.bat.xyz以来archive/不是// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.2.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { jcenter() } } task clean(type: Delete) { delete rootProject.buildDir }

我发现this有助于根据模式识别唯一值,但我无法弄清楚如何将其与我在存档中不匹配的附加条款相结合/

2 个答案:

答案 0 :(得分:2)

这里实际上不需要awk,你可以用简单的grep / sed和sort来实现:

(ls ./archive | sed 's/^/1 /'; ls ./active | sed 's/^/2 /') | \
  sort --field-separator="." --key="2,2" --uniq --stable | \
  grep '^2 ' | sed 's/^2 //'

<强>解释

首先列出两个目录并标记哪个行来自哪个目录。然后按照中间部分对两个列表进行排序。选项--field-separator="."将所有行拆分为dosts上的字段,选项--key="2,2"告诉按中间字段排序,即按点之间的部分排序。我们使用稳定的排序来确保存档中的行是第一行并告诉排序只打印所有重复行的第一个匹配。

最后,我们只会过滤使用2标记的行,即来自./active的行。

示例:

active/
  foo.aaa.xxx
  foo.bar.abc
  foo.bar.xyz
  foo.bat.abc
  zoo.aaa.xxx
  zoo.bbb.aaa


archive/
  aaa.bbb.zoo
  foo.bat.xyz

Result:
  foo.aaa.xxx
  foo.bar.abc

答案 1 :(得分:1)

使用MainActivityGNU grepawk

的另一次尝试
GNU findutils

使用process-substitution <()运行$ grep -Fxvf <(find active/ -type f -printf '%P\n' | awk -F'.' '!seen[$2]++') <(find archive/ -type f -printf '%P\n' | awk -F'.' '!seen[$2]++') foo.bar.xyz / find命令并将其传递给awk以查找差异。

虽然grep命令列出了指定目录中的文件,每行一个条目,但find通过保留awk字未复制的列表来过滤列表。对于2nd,分隔符为awk .仅在以前未见过的情况下,通过在数组中对其进行散列来打印唯一的行。

请记住!seen[$2]++中的-printf '%P POSIX兼容,并且可以使用find。建议升级到它以便工作。

其他可能的解决方案,具有类似逻辑,GNU findutilscommjoin的一部分如下: -

GNU coreutils

另一位$ join -v 2 <(find active/ -type f -printf '%P\n' | awk -F'.' '!seen[$2]++') <(find archive/ -type f -printf '%P\n' | awk -F'.' '!seen[$2]++') foo.bar.xyz

comm