如何根据某些条件使用 shell 脚本从文本文件中删除几行数据
how to delete few rows of data from a text file using shell scripting based on some conditions
我有一个超过 10 万行的文本文件。下面提到的数据是我拥有的文本文件的示例。我想对此数据使用一些条件并删除一些行。文本文件没有 headers (ID,NAME,Code-1,code,2-code-3)。我提到了以供参考。我如何使用 shell 脚本实现此目的?
输入测试文件:
| ID | NAME | Code-1 | code-2 | code-3 |
| $$ | 5HF | 1E | N | Y |
| $$ | 2MU | 3C | N | Y |
| $$ | 32E | 3C | N | N |
| AB | 3CH | 3C | N | N |
| MK | A1M | AS | P | N |
| $$ | Y01 | 01 | F | Y |
| $$ | BG0 | 0G | F | N |
条件:
- 如果 code-2 = 'N' 和 code-1 不等于 ( '3C' , '3B' , '32' , '31' , '3D' ) 那么 ID='$$'
- if code-2 ='N' and code-1 equal to ( '3C' , '3B' , '32' , '31' , '3D') 然后接受任何 ID 和(接受 ID ='$$' 仅当 code-3='Y')'
- if code-2 != 'N' then accept (ID='$$' only if code-3='Y') and all other IDs
输出:
| ID | NAME | Code-1 | code-2 | code-3 |
| $$ | 5HF | 1E | N | Y |
| $$ | 2MU | 3C | N | Y |
| AB | 3CH | 3C | N | N |
| MK | A1M | AS | P | N |
| $$ | Y01 | 01 | F | Y |
鼓励您在提问时展示自己的努力。但我知道如果您是 Bash 的新手,这个问题可能会很复杂。这是我使用 awk 的解决方案。在我的计算机上花费 0.545 秒处理了 137k 行(中等规格)。
awk '{
ID=; NAME=; CODE1=; CODE2=; CODE3=;
if (CODE2 == "N") {
if (CODE1 ~ /(3C|3B|32|31|3D)/) {
if (ID == "$$") {
if (CODE3 == "Y") {
print;
}
}
else {
print;
}
}
else {
if (ID == "$$") {
print;
}
}
}
else {
if (ID == "$$") {
if (CODE3 == "Y") {
print;
}
}
else {
print;
}
}}' file
注意它有一定的限制:
a) 它用空格而不是 |
来分隔值。它将适用于您的确切输入格式,但不适用于没有额外空格的输入行,例如
|$$|32E|3C|N|N|
|AB|3CH|3C|N|N|
b) 出于同样的原因,如果 col 值有额外的空格,该命令将生成不正确的结果,例如
| $$ | 32E FOO | 3C | N | N |
| AB | 3CH BBT | 3C | N | N |
我有一个超过 10 万行的文本文件。下面提到的数据是我拥有的文本文件的示例。我想对此数据使用一些条件并删除一些行。文本文件没有 headers (ID,NAME,Code-1,code,2-code-3)。我提到了以供参考。我如何使用 shell 脚本实现此目的?
输入测试文件:
| ID | NAME | Code-1 | code-2 | code-3 |
| $$ | 5HF | 1E | N | Y |
| $$ | 2MU | 3C | N | Y |
| $$ | 32E | 3C | N | N |
| AB | 3CH | 3C | N | N |
| MK | A1M | AS | P | N |
| $$ | Y01 | 01 | F | Y |
| $$ | BG0 | 0G | F | N |
条件:
- 如果 code-2 = 'N' 和 code-1 不等于 ( '3C' , '3B' , '32' , '31' , '3D' ) 那么 ID='$$'
- if code-2 ='N' and code-1 equal to ( '3C' , '3B' , '32' , '31' , '3D') 然后接受任何 ID 和(接受 ID ='$$' 仅当 code-3='Y')'
- if code-2 != 'N' then accept (ID='$$' only if code-3='Y') and all other IDs
输出:
| ID | NAME | Code-1 | code-2 | code-3 |
| $$ | 5HF | 1E | N | Y |
| $$ | 2MU | 3C | N | Y |
| AB | 3CH | 3C | N | N |
| MK | A1M | AS | P | N |
| $$ | Y01 | 01 | F | Y |
鼓励您在提问时展示自己的努力。但我知道如果您是 Bash 的新手,这个问题可能会很复杂。这是我使用 awk 的解决方案。在我的计算机上花费 0.545 秒处理了 137k 行(中等规格)。
awk '{
ID=; NAME=; CODE1=; CODE2=; CODE3=;
if (CODE2 == "N") {
if (CODE1 ~ /(3C|3B|32|31|3D)/) {
if (ID == "$$") {
if (CODE3 == "Y") {
print;
}
}
else {
print;
}
}
else {
if (ID == "$$") {
print;
}
}
}
else {
if (ID == "$$") {
if (CODE3 == "Y") {
print;
}
}
else {
print;
}
}}' file
注意它有一定的限制:
a) 它用空格而不是 |
来分隔值。它将适用于您的确切输入格式,但不适用于没有额外空格的输入行,例如
|$$|32E|3C|N|N|
|AB|3CH|3C|N|N|
b) 出于同样的原因,如果 col 值有额外的空格,该命令将生成不正确的结果,例如
| $$ | 32E FOO | 3C | N | N |
| AB | 3CH BBT | 3C | N | N |