我的目标是制作优雅的单面纸。
输入:
源文件,包含字符串列表:
foo123
bar12356
foo999
var8292
bar922
link991
bar8
var000
具有黑名单模式的文件:
bar
link
白名单文件(可以包含多个条目):
bar922
任务: 我们需要根据黑名单中的模式删除字符串,同时保留白名单中的精确匹配项。需要注意的是,我们都需要以与原始文件中相同的顺序保存输出,并且如果白名单字符串在初始文件中不存在,我们不应该添加白名单字符串< / em>。
输出:
foo123
foo999
var8292
bar922
var000
答案 0 :(得分:2)
您可以为此使用<FieldArray name="policies" component={this.renderPolicies} />
这个小命令。这个想法是您在黑名单文件(renderPolicies = ({ fields, meta }) => {
return (
<ul>
<li>
<button type="button" onClick={() => fields.push({})}>
Add Policy
</button>
{this.renderError(meta)}
</li>
{fields.map((policy, index) => (
<li key={index}>
<button
type="button"
title="Remove Policy"
onClick={() => fields.remove(index)}
/>
<h4>Policy #{index + 1}</h4>
<Field
name={`${policy}.id`}
type="text"
component={renderInput}
label="Id"
/>
</li>
))}
</ul>
);
)上使用awk
命令,使其内容用paste
分隔,例如bl
以及白名单文件(|
)。
生成文件后,我们对文件的内容进行正则表达式匹配,条件是这些条目可能在白名单中,或者这些条目不应该在黑名单中。
bar|link
注释中有一点要处理wl
文件中的空行。如果您怀疑它们,请使用awk -v bl=$(paste -sd'|' bl) -v wl=$(paste -sd'|' wl) '$0 ~ wl || $0 !~ bl' file
对其进行修复。
答案 1 :(得分:2)
David C. Rankin的解决方案非常优雅,不会造成太多混乱。如果要保留顺序,可以将其扩展为:
$ { grep -wf wl file; grep -vf bl file ;} | grep -wf - file
请注意,我们为白名单引入了-w
标志,以确保单词匹配。
备注:这是一个合格的解决方案,它是迄今为止最有效的解决方案!
答案 2 :(得分:1)
您可以使用grep -f
创建一个简单的 one-liner 来从您的白名单和黑名单文件中读取模式,并包括-v
以将黑名单的内容反转列表,然后使用stdin
上的组合结果来创建有序文件,例如
输入,白名单,黑名单文件
$ cat file
foo123
bar12356
foo999
var8292
bar922
link991
bar8
var000
白名单
$ cat white
bar922
黑名单
$ cat black
bar
link
修改
与@kvantour进行沟通工作后,您可以使用流程替换来在stdin
上为列表进行最终排序,例如
$ grep -wof - file < <(grep -v -f black file; grep -f white file)
foo123
foo999
var8292
bar922
var000
答案 3 :(得分:0)
也可以使用Perl解决此问题。
> cat stan.in
foo123
bar12356
foo999
var8292
bar922
link991
bar8
var000
> cat white
bar922
> cat black
bar
link
> perl -lne 'BEGIN{ @w=qx(cat white);@b=qx(cat black);}chomp for(@w);chomp for(@b); $x=$_;print if grep {$x=~/$_/} @w; print if scalar(grep { $x=~/$_/g} @b)==0' stan.in
foo123
foo999
var8292
bar922
var000
>
或
$ perl -lne 'BEGIN{ @w=qx(cat white);@b=qx(cat black);}chomp for(@w,@b);$x=$_;print if grep {$x=~/$_/} @w; print if scalar(grep { $x=~/$_/g} @b)==0' stan.in
foo123
foo999
var8292
bar922
var000
答案 4 :(得分:0)
只是为了好玩,这是一个使用bash数组的选项 1 :
# Gather our lists...
mapfile -t a < input.txt; mapfile -t wl < wl; mapfile -t bl < bl
# And store the whitelist as indices for easier handling...
declare -A wl_a=(); for x in "${wl[@]}"; do wl_a["$x"]=1; done
# Then step through the data array,
for x in "${!a[@]}"; do
# detecting and skipping whitelist matches,
[[ "${wl_a[${a[$x]}]}" = 1 ]] &&
printf 'wl: %s\n' "$x" &&
continue
# and deleting blacklist matches.
for y in "${bl[@]}"; do
[[ "${a[$x]}" = "$y"* ]] &&
printf 'bl: %s\n' "${a[$x]}" &&
unset a["$x"]
done
done
结果是数组${a[@]}
以原始顺序包含您的数据,并删除了适当的黑名单项目。您可以使用declare -p a
或printf '%s\n' "${a[@]}"
查看结果。
请注意,这是实现这一目标的一种 crazy 方法(而且显然不是单一方法),您可以在awk中更有效地完成很多工作。但这至少是一个纯bash解决方案,并且不使用任何外部工具。
1。这取决于bash 4+,因为其中一个数组是关联的。