我有一个包含数十万条记录的文件。所有这些记录都是唯一的,用逗号分隔的值。第一列可以认为是关键,第二列是感兴趣的值。
文件大小为8到10 MB。我必须不时在脚本中查找这些值。目前,我正在使用以下grep语句:
myvalue = $(grep $ myvar文件名| cut -d,-f2)
它可以正常工作,但是真正的问题是对同一文件的多次/顺序查找。我认为这不是一种非常优化的方法,因为在脚本运行期间我必须多次从同一文件中查找(超过100-200次),因此每次都要grep整个文件。我想要一些更好/优化的方法。
更新 需要特别注意的是它是顺序脚本,并且$ myvar中的所有值都是在运行时生成的,所以我不能拥有所有可用值并进行组合查找,因此每次迭代都必须是一个值查找
答案 0 :(得分:2)
我要考虑的显而易见的事情是Type
结果的局限性,这可以通过public class RequestOperation {
public enum Type {
//enum values and mappings
}
private String applicationUrl;
private ArrayList<String> requestParams = new ArrayList<>();
public RequestOperation(Type operationType) {
this.applicationUrl = composeUrl(operationType, requestParams);
}
public RequestOperation(Type operationType, String paramFirst) {
this.requestParams.add(0, paramFirst);
new RequestOperation(operationType);
}
public RequestOperation(Type operationType, String paramFirst, String paramSecond) {
this.requestParams.add(0, paramSecond);
new RequestOperation(operationType, paramFirst);
}
public RequestOperation(Type operationType, String paramFirst, String paramSecond, String paramThird) {
this.requestParams.add(0, paramThird);
new RequestOperation(operationType, paramFirst, paramSecond);
}
开关来完成:
grep
答案 1 :(得分:2)
如果文件一次构造,然后一遍又一遍地引用而又没有在其间进行更改,则需要使用关联数组作为查找表。这可能会变得越来越丑陋。考虑使用perl。
但是,您问如何用bash进行操作。
$: eval "declare -A lookup=(
$( sed -E 's/^([^,]+),([^,]+).*/ [\1]=\2/' filename )
)"
现在所有值都应在表lookup
中。
关联数组使用字符串作为键而不是整数,因此这会将键和值设置为表中的对。
sed -E 's/^([^,]+),([^,]+).*/ [\1]=\2/'
采用逗号分隔文件的第一和第二字段,并将其重新格式化为bash语法的键/值分配,如下所示:
declare -A lookup=(
[a]=1
[b]=2
[c]=3 # ... and so on
)
eval
将所有内容解析到当前环境中供您使用。
没有其他grep
。只需使用"${lookup[$myvar]}"
。
如果您只是想为其分配可读性,请使用{p>而不是grep
myvalue="${lookup[$myvar]}"
我正在使用的本地示例
$: cat x
a,1,lijhgf
b,2,;lsaoidj
c,3,;l'skd
$: echo "declare -A lookup=(
$( sed -E 's/^([^,]+),([^,]+).*/ [\1]=\2/' x )
)"
declare -A lookup=(
[a]=1
[b]=2
[c]=3
)
$: eval "declare -A lookup=(
$( sed -E 's/^([^,]+),([^,]+),.*/ [\1]=\2/' x )
)"
$: echo "${lookup[b]}"
2
答案 2 :(得分:1)
首先,让我们看一下您的命令:
myvalue=$(grep $myvar filename | cut -d, -f2)
您使用加载的2个二进制文件(grep
和cut
)来处理数据。您应该尝试将其减少为单个二进制文件。这已经很有帮助:
myvalue=$(awk -F, -v var="$myvar" '$0~var { print $2; exit}' filename)
这将更快:
如果您需要根据第一列中的键进行多次查找,则可以在bash中执行以下操作:
while IFS= read -r; do
declare -A z+="( $REPLY )"
done < <(awk -F, '{print "["$1"]="$0}' lookupfile)
echo ${z[$key]}
基于How do I populate a bash associative array with command output?