如何将文本文件中的特定单元格左移
How to shift a specific cell left in a text file
我有一个非常大的文本文件(tab-delimited,第一行是 header),如下所示:
A1 A2 A3 A4 A5 A6 A7
FA1 AB 234 231 0.02 456 I
FA2 ACE 241 2154 0.1 324 O
FA3 AD AC 150 2367 0.02 123 I
FA AFQ ASB 123 2473 0.4 630 I
如您所见,第 3 列第 3 行和第 4 列 (A3) 处有两个字符串。你能帮我解决一下如何删除这些字符串并使用 awk、sed 或任何 Linux 代码将单元格移动到更正后的文件中,例如:
A1 A2 A3 A4 A5 A6 A7
FA1 AB 234 231 0.02 456 I
FA2 ACE 241 2154 0.1 324 O
FA3 AD 150 2367 0.02 123 I
FA AFQ 123 2473 0.4 630 I
我试过了:
awk 'if(!~/[0-9]+/') =}1', file
它删除第 3 列中的所有字符串并用第 4 列替换它们,但不向左移动单元格。
使用sed
$ sed '1!s/^\([^ ]* \+[^ ]* \+\)[A-Z][^ ]* \+//' input_file
A1 A2 A3 A4 A5 A6 A7
FA1 AB 234 231 0.02 456 I
FA2 ACE 241 2154 0.1 324 O
FA3 AD 150 2367 0.02 123 I
FA AFQ 123 2473 0.4 630 I
1!
- 不匹配第 1 行
^\([^ ]* \+[^ ]* \+\)
- 使用反向引用,我们可以将括号的内容存储到内存中,这将匹配直到第二个 space.
的所有内容
[A-Z][^ ]* \+
- 任何不在括号内的内容都将从匹配的 return 中排除。如果第三列包含大写字母字符,则排除直到下一个 space 的所有内容。
- Return 括号内捕获的任何内容
你可以使用这个awk
:
awk 'BEGIN{FS=OFS="\t"} NR > 1 && +0 != {
= ""; sub(FS FS, FS)} 1' file
A1 A2 A3 A4 A5 A6 A7
FA1 AB 234 231 0.02 456 I
FA2 ACE 241 2154 0.1 324 O
FA3 AD 150 2367 0.02 123 I
FA AFQ 123 2473 0.4 630 I
这可能对你有用 (GNU sed):
sed -E '1!s/^((\S+\s+){2})[A-Z]\S+\s+//' file
如果第三个字段以字符 A
到 Z
.
开头,则删除第三个字段和后面的 space(s)
$ awk -F'\t+' -v OFS='\t' 'NF>7{=""; [=10=]=[=10=]; =} 1' file
A1 A2 A3 A4 A5 A6 A7
FA1 AB 234 231 0.02 456 I
FA2 ACE 241 2154 0.1 324 O
FA3 AD 150 2367 0.02 123 I
FA AFQ 123 2473 0.4 630 I
$ awk -v OFS='\t' '{print , , $(NF-4), $(NF-3), $(NF-2), $(NF-1), $NF}' file
A1 A2 A3 A4 A5 A6 A7
FA1 AB 234 231 0.02 456 I
FA2 ACE 241 2154 0.1 324 O
FA3 AD 150 2367 0.02 123 I
FA AFQ 123 2473 0.4 630 I
使用cppawk:
cppawk '
#include <cons.h> // numberp lives here
#include <field.h> // delf here
NR > 1 && !numberp() { delf(3); } 1' file
A1 A2 A3 A4 A5 A6 A7
FA1 AB 234 231 0.02 456 I
FA2 ACE 241 2154 0.1 324 O
FA3 AD 150 2367 0.02 123 I
FA AFQ 123 2473 0.4 630 I
我有一个非常大的文本文件(tab-delimited,第一行是 header),如下所示:
A1 A2 A3 A4 A5 A6 A7
FA1 AB 234 231 0.02 456 I
FA2 ACE 241 2154 0.1 324 O
FA3 AD AC 150 2367 0.02 123 I
FA AFQ ASB 123 2473 0.4 630 I
如您所见,第 3 列第 3 行和第 4 列 (A3) 处有两个字符串。你能帮我解决一下如何删除这些字符串并使用 awk、sed 或任何 Linux 代码将单元格移动到更正后的文件中,例如:
A1 A2 A3 A4 A5 A6 A7
FA1 AB 234 231 0.02 456 I
FA2 ACE 241 2154 0.1 324 O
FA3 AD 150 2367 0.02 123 I
FA AFQ 123 2473 0.4 630 I
我试过了:
awk 'if(!~/[0-9]+/') =}1', file
它删除第 3 列中的所有字符串并用第 4 列替换它们,但不向左移动单元格。
使用sed
$ sed '1!s/^\([^ ]* \+[^ ]* \+\)[A-Z][^ ]* \+//' input_file
A1 A2 A3 A4 A5 A6 A7
FA1 AB 234 231 0.02 456 I
FA2 ACE 241 2154 0.1 324 O
FA3 AD 150 2367 0.02 123 I
FA AFQ 123 2473 0.4 630 I
1!
- 不匹配第 1 行
^\([^ ]* \+[^ ]* \+\)
- 使用反向引用,我们可以将括号的内容存储到内存中,这将匹配直到第二个 space.
[A-Z][^ ]* \+
- 任何不在括号内的内容都将从匹配的 return 中排除。如果第三列包含大写字母字符,则排除直到下一个 space 的所有内容。
- Return 括号内捕获的任何内容
你可以使用这个awk
:
awk 'BEGIN{FS=OFS="\t"} NR > 1 && +0 != {
= ""; sub(FS FS, FS)} 1' file
A1 A2 A3 A4 A5 A6 A7
FA1 AB 234 231 0.02 456 I
FA2 ACE 241 2154 0.1 324 O
FA3 AD 150 2367 0.02 123 I
FA AFQ 123 2473 0.4 630 I
这可能对你有用 (GNU sed):
sed -E '1!s/^((\S+\s+){2})[A-Z]\S+\s+//' file
如果第三个字段以字符 A
到 Z
.
$ awk -F'\t+' -v OFS='\t' 'NF>7{=""; [=10=]=[=10=]; =} 1' file
A1 A2 A3 A4 A5 A6 A7
FA1 AB 234 231 0.02 456 I
FA2 ACE 241 2154 0.1 324 O
FA3 AD 150 2367 0.02 123 I
FA AFQ 123 2473 0.4 630 I
$ awk -v OFS='\t' '{print , , $(NF-4), $(NF-3), $(NF-2), $(NF-1), $NF}' file
A1 A2 A3 A4 A5 A6 A7
FA1 AB 234 231 0.02 456 I
FA2 ACE 241 2154 0.1 324 O
FA3 AD 150 2367 0.02 123 I
FA AFQ 123 2473 0.4 630 I
使用cppawk:
cppawk '
#include <cons.h> // numberp lives here
#include <field.h> // delf here
NR > 1 && !numberp() { delf(3); } 1' file
A1 A2 A3 A4 A5 A6 A7
FA1 AB 234 231 0.02 456 I
FA2 ACE 241 2154 0.1 324 O
FA3 AD 150 2367 0.02 123 I
FA AFQ 123 2473 0.4 630 I