我有一个包含两列的大文件:
tiago@tiago:~/$ head Ids.txt
TRINITY_DN126999_c0_g1_i1 ENSMUST00000040656.6
TRINITY_DN126999_c0_g1_i1 ENSMUST00000040656.6
TRINITY_DN126906_c0_g1_i1 ENSMUST00000126770.1
TRINITY_DN126907_c0_g1_i1 ENSMUST00000192613.1
TRINITY_DN126988_c0_g1_i1 ENSMUST00000032372.6
.....
我有另一个包含数据的文件,如下所示:
"baseMean" "log2FoldChange" "lfcSE" "stat" "pvalue" "padj" "super" "sub" "threshold"
"TRINITY_DN41319_c0_g1" 178.721774751278 2.1974294626636 0.342621318593487 6.41358066008381 1.4214085388179e-10 5.54686423073089e-08 TRUE FALSE "TRUE"
"TRINITY_DN87368_c0_g1" 4172.76139849472 2.45766387851112 0.404014016558211 6.08311538160958 1.17869459181235e-09 4.02673069375893e-07 TRUE FALSE "TRUE"
"TRINITY_DN34622_c0_g1" 39.1949851245197 3.28758092748061 0.54255370348027 6.05945716781964 1.3658169042862e-09 4.62597265729593e-07 TRUE FALSE "TRUE"
.....
我正在考虑使用sed在数据文件的第一列中执行值的转换,使用第一个文件作为字典。
也就是说,依次考虑数据文件的每一行,如果第一列中的值与字典文件的第一列中的值匹配,则将进行替换;否则,该行就会被打印出来。
任何建议都将不胜感激。
答案 0 :(得分:1)
您可以将第一个文件Ids.txt
转换为sed脚本:
$ sed -r 's| *(\S+) (\S+)|s/^"\1/"\2/|' Ids.txt > repl.sed
$ cat repl.sed
s/^"TRINITY_DN126999_c0_g1_i1/"ENSMUST00000040656.6/
s/^"TRINITY_DN126999_c0_g1_i1/"ENSMUST00000040656.6/
s/^"TRINITY_DN126906_c0_g1_i1/"ENSMUST00000126770.1/
s/^"TRINITY_DN126907_c0_g1_i1/"ENSMUST00000192613.1/
s/^"TRINITY_DN126988_c0_g1_i1/"ENSMUST00000032372.6/
这将删除前导空格并使每一行成为替换命令。
然后,您可以使用此脚本在数据文件中执行替换:
sed -f repl.sed datafile
...重定向到另一个文件,或与sed -i
一起就地。
如果您没有GNU sed,可以使用第一个命令的POSIX符合版本:
sed 's| *\([^ ]*\) \([^ ]*\)|s/^"\1/"\2/|' Ids.txt
这使用基本而非扩展的正则表达式,并使用[^ ]
代替\S
而不是def word_len_dict(text):
the_dict = {}
user_input = str(text)
words_list = user_input.split()
for word in words_list:
if len(word) in the_dict:
the_dict[len(word)] += [word]
else:
the_dict[len(word)] = [word]
return the_dict
。
答案 1 :(得分:1)
由于第一个文件(字典文件)很大,使用sed
可能会非常慢;更快,更复杂的方法是使用awk
,如下所示:
awk -v col=1 -v dict=Ids.txt '
BEGIN {while(getline<dict){a["\""$1"\""]="\""$2"\""} }
$col in a {$col=a[$col]}; {print}'
(此处,“Ids.txt”是字典文件,“col”是数据文件中感兴趣字段的列号。)
此方法还具有不需要对字典文件进行任何修改的优点。
答案 2 :(得分:0)
#!/bin/bash
# Declare hash table
declare -A Ids
# Go though first input file and add key-value pairs to hash table
while read Id; do
key=$(echo $Id | cut -d " " -f1)
value=$(echo $Id | cut -d " " -f2)
Ids+=([$key]=$value)
done < $1
# Go through second input file and replace every first column with
# the corresponding value in the hash table if it exists
while read line; do
first_col=$(echo $line | cut -d '"' -f2)
new_id=${Ids[$first_col]}
if [ -n "$new_id" ]; then
sed -i s/$first_col/$new_id/g $2
fi
done < $2
我会将脚本称为
./script.sh Ids.txt data.txt