根据匹配多个值之一的列提取行
Extract lines based on a column matching one of multiple values
我有一些文件包含以下数据:
160-68 160 68 B-A 0011 3.80247
160-68 160 68 B-A 0022 3.73454
160-69 160 69 B-A 0088 2.76641
160-69 160 69 B-A 0022 3.54446
160-69 160 69 B-A 0088 4.24609
160-69 160 69 B-A 0011 3.97644
160-69 160 69 B-A 0021 1.82292
我需要在第 5 列的数组中提取具有任何值(可以为负数:ex -12222)的行。
输出 [0088, 0021]:
160-69 160 69 B-A 0088 2.76641
160-69 160 69 B-A 0088 4.24609
160-69 160 69 B-A 0021 1.82292
我目前正在使用 Ruby 执行此操作,但有没有一种方法可以使用 Bash 更快地执行此操作?
谢谢。
bash 不太可能比 ruby 快:bash 通常很慢。我会选择 awk 或 perl
awk -v values="0088 0021" '
BEGIN {
n = split(values, a)
for (i=1; i<=n; i++) b[a[i]]=1
}
in b
' file
perl -ane 'BEGIN {%v = ("0088"=>1, "0021"=>1)} print if $v{$F[4]}' file
这是一个基于 egrep 的解决方案。
假设特殊值数组以简单的 CSV 字符串形式给出,例如
A="0088,0021"
然后下面的 egrep 调用将 select 所需的行:
egrep "( [^ ]+){3} ($(tr , '|' <<< "$A")) "
实际上,最好修改上面的正则表达式,使其在输入格式方面不那么脆弱。
如果数组的元素($A) 包含egrep 特有的字符(如方括号、圆括号等),则需要注意对它们进行转义。这可以通过编程方式完成,例如
A=$(sed 's/[]\.|$(){}?+*^]/\&/g' <<< "$A")
另请参阅下面的评论。
另一个解决方案
#!/bin/bash
for i in "$@"
do
while read column
do
arr=(${column})
if [ ${arr[4]} = $i ]
then
echo $column
fi
done < input.txt
done
其中 input.txt 是数据文件,您将此脚本称为
./脚本名称 0088 0021
我有一些文件包含以下数据:
160-68 160 68 B-A 0011 3.80247
160-68 160 68 B-A 0022 3.73454
160-69 160 69 B-A 0088 2.76641
160-69 160 69 B-A 0022 3.54446
160-69 160 69 B-A 0088 4.24609
160-69 160 69 B-A 0011 3.97644
160-69 160 69 B-A 0021 1.82292
我需要在第 5 列的数组中提取具有任何值(可以为负数:ex -12222)的行。
输出 [0088, 0021]:
160-69 160 69 B-A 0088 2.76641
160-69 160 69 B-A 0088 4.24609
160-69 160 69 B-A 0021 1.82292
我目前正在使用 Ruby 执行此操作,但有没有一种方法可以使用 Bash 更快地执行此操作?
谢谢。
bash 不太可能比 ruby 快:bash 通常很慢。我会选择 awk 或 perl
awk -v values="0088 0021" '
BEGIN {
n = split(values, a)
for (i=1; i<=n; i++) b[a[i]]=1
}
in b
' file
perl -ane 'BEGIN {%v = ("0088"=>1, "0021"=>1)} print if $v{$F[4]}' file
这是一个基于 egrep 的解决方案。
假设特殊值数组以简单的 CSV 字符串形式给出,例如
A="0088,0021"
然后下面的 egrep 调用将 select 所需的行:
egrep "( [^ ]+){3} ($(tr , '|' <<< "$A")) "
实际上,最好修改上面的正则表达式,使其在输入格式方面不那么脆弱。
如果数组的元素($A) 包含egrep 特有的字符(如方括号、圆括号等),则需要注意对它们进行转义。这可以通过编程方式完成,例如
A=$(sed 's/[]\.|$(){}?+*^]/\&/g' <<< "$A")
另请参阅下面的评论。
另一个解决方案
#!/bin/bash
for i in "$@"
do
while read column
do
arr=(${column})
if [ ${arr[4]} = $i ]
then
echo $column
fi
done < input.txt
done
其中 input.txt 是数据文件,您将此脚本称为 ./脚本名称 0088 0021