使用 bash 创建包含数据中现有列的子字符串的新列
create new column containing a substring of an existing column in data using bash
我有一个大 tsv.gz 文件 (40GB),我想从现有变量 col3
中提取一个字符串,将其存储在新变量 New_var
中(放置在开头)并将所有内容保存到新文件中。
数据示例“old_file.tsv.gz”
col1 col2 col3 col4
1 positive 12:1234A 100
2 negative 10:9638B 110
3 positive 5:0987A 100
4 positive 8:5678A 170
所需数据“new_file.tsv.gz”
New_var col1 col2 col3 col4
12 1 positive 12:1234A 100
10 2 negative 10:9638B 110
5 3 positive 5:0987A 100
8 4 positive 8:5678A 170
我是 bash 的新人,所以我尝试了很多东西但我卡住了,我已经尝试了
zcat old_file.tsv.gz | awk '{print New_var=,[=13=] }' | awk ' ~ /^[0-9]:/{print [=13=] | (gzip -c > new_file.tsv.gz) }'
我想我有很多问题。 {print New_var=,[=16=] }
确实创建了 col3
的副本,但没有重命名。然后,当我添加代码的最后一部分时 awk ' ~ /^[0-9]:/{print [=18=] | (gzip -c > new_file.tsv.gz) }'
... 什么也没有出现(我试图查看是否忘记了括号但找不到问题)。
另外我不确定这种方式是否是最好的方式。
知道如何让它发挥作用吗?
在单独的文件中制作一个 AWK 脚本(为了便于阅读),比如 1.awk
:
{ if (NR > 1) {
# all data lines
split(, a, ":");
print a[1], , , , ;
} else {
# header line
print "new_var", , , , ;
}
}
现在用 AWK 文件处理输入(比如 1.csv.gz
):
zcat 1.csv.gz | awk -f 1.awk | gzip -c > 1_new.csv.gz
我建议使用一个制表符 (\t
) 和 :
作为输入字段分隔符:
awk 'BEGIN { FS="[\t:]"; OFS="\t" }
NR==1 { ="New_var" OFS }
NR>1 { [=10=]= OFS [=10=] }
{ print }'
作为一行:
awk 'BEGIN{ FS="[\t:]"; OFS="\t" } NR==1{ ="New_var" OFS } NR>1{ [=11=]= OFS [=11=] } { print }'
参见:8 Powerful Awk Built-in Variables – FS, OFS, RS, ORS, NR, NF, FILENAME, FNR
我有一个大 tsv.gz 文件 (40GB),我想从现有变量 col3
中提取一个字符串,将其存储在新变量 New_var
中(放置在开头)并将所有内容保存到新文件中。
数据示例“old_file.tsv.gz”
col1 col2 col3 col4
1 positive 12:1234A 100
2 negative 10:9638B 110
3 positive 5:0987A 100
4 positive 8:5678A 170
所需数据“new_file.tsv.gz”
New_var col1 col2 col3 col4
12 1 positive 12:1234A 100
10 2 negative 10:9638B 110
5 3 positive 5:0987A 100
8 4 positive 8:5678A 170
我是 bash 的新人,所以我尝试了很多东西但我卡住了,我已经尝试了
zcat old_file.tsv.gz | awk '{print New_var=,[=13=] }' | awk ' ~ /^[0-9]:/{print [=13=] | (gzip -c > new_file.tsv.gz) }'
我想我有很多问题。 {print New_var=,[=16=] }
确实创建了 col3
的副本,但没有重命名。然后,当我添加代码的最后一部分时 awk ' ~ /^[0-9]:/{print [=18=] | (gzip -c > new_file.tsv.gz) }'
... 什么也没有出现(我试图查看是否忘记了括号但找不到问题)。
另外我不确定这种方式是否是最好的方式。
知道如何让它发挥作用吗?
在单独的文件中制作一个 AWK 脚本(为了便于阅读),比如 1.awk
:
{ if (NR > 1) {
# all data lines
split(, a, ":");
print a[1], , , , ;
} else {
# header line
print "new_var", , , , ;
}
}
现在用 AWK 文件处理输入(比如 1.csv.gz
):
zcat 1.csv.gz | awk -f 1.awk | gzip -c > 1_new.csv.gz
我建议使用一个制表符 (\t
) 和 :
作为输入字段分隔符:
awk 'BEGIN { FS="[\t:]"; OFS="\t" }
NR==1 { ="New_var" OFS }
NR>1 { [=10=]= OFS [=10=] }
{ print }'
作为一行:
awk 'BEGIN{ FS="[\t:]"; OFS="\t" } NR==1{ ="New_var" OFS } NR>1{ [=11=]= OFS [=11=] } { print }'
参见:8 Powerful Awk Built-in Variables – FS, OFS, RS, ORS, NR, NF, FILENAME, FNR