Car*_* H. 0 command-line text-processing csv
我有一个只有 2 列(但有很多行)的 CSV 文件,偶尔会有不规则行,这些行始终以星号 (*) 字符开头,并且可能跨越两列以上。仅使用 Linux 命令行,预期行为是:
例如,如果我有一个包含以下内容的 CSV:
0,Apple
1,Apple
2,Apple
* Checkpoint
* Another checkpoint
3,Apple
4,Apple
5,Box
6,Box
7,Citrus
8,Box
9,Apple
10,Apple
11,Apple
12,Dove
13,Citrus
* Sudden checkpoint, * Leftover checkpoint note 1, * Leftover checkpoint note N
14,Citrus
15,Citrus
16,Citrus
17,Apple
18,Citrus
Run Code Online (Sandbox Code Playgroud)
之后应该如下所示:
0,Apple
* Checkpoint
* Another checkpoint
4,Apple
5,Box
6,Box
7,Citrus
8,Box
9,Apple
11,Apple
12,Dove
13,Citrus
* Sudden checkpoint, * Leftover checkpoint note 1, * Leftover checkpoint note N
16,Citrus
17,Apple
18,Citrus
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,第 1 至 3 行、第 10 行和第 14 至 15 行被删除。
预先非常感谢您的任何答复。
干杯
使用awk
:
BEGIN { FS = "," }
/^[*]/ { print; next }
{
if (NR > 1 && $2 == word) {
tail = $0
++count
} else {
if (count) print tail
word = $2; count = 0
print
}
}
END { if (count) print tail }
Run Code Online (Sandbox Code Playgroud)
该awk
脚本无条件打印所有以 开头的行*
。如果该行不是这样的行,并且如果第二个字段中的单词是我们记住的单词,则将该记录存储在变量中tail
(“tail”,如一系列记录中具有相同单词的最后一条记录)第二个字段)。
如果第二个字段与前一个字段不同,则打印尾部记录;如果上一次记录中有多个记录,则记住新单词并打印当前记录(新一次记录中的第一条记录)第二个字段中具有相同单词的一条或多条记录)。
根据提供的数据进行测试并假设它是简单的 CSV(意味着没有嵌入的分隔符或换行符等):
$ awk -f script file
0,Apple
* Checkpoint
* Another checkpoint
4,Apple
5,Box
6,Box
7,Citrus
8,Box
9,Apple
11,Apple
12,Dove
13,Citrus
* Sudden checkpoint, * Leftover checkpoint note 1, * Leftover checkpoint note N
16,Citrus
17,Apple
18,Citrus
Run Code Online (Sandbox Code Playgroud)
与上面类似,但使用Miller ( mlr
),它支持 CSV,并且能够处理带有复杂引号字符串的 CSV 记录:
if (is_not_null(@word) && $2 == @word) {
@tail = $*;
false # omit this record for now
} else {
is_not_null(@tail) {
emit @tail # emit the tail record
}
@word = $2; @tail = null;
true # emit this record
}
end { is_not_null(@tail) { emit @tail } }
Run Code Online (Sandbox Code Playgroud)
filter
这是 Miller子命令的表达式,用于使用与awk
上述代码非常相似的逻辑来包含或省略输入数据集中的记录。我们可以通过命令行中的*
use 来让 Miller 遍历以该字符开头的行。--pass-comments-with='*'
使用--csv
with-N
将输入视为无标头 CSV。
$ mlr --pass-comments-with='*' --csv -N filter -f script file
0,Apple
* Checkpoint
* Another checkpoint
4,Apple
5,Box
6,Box
7,Citrus
8,Box
9,Apple
11,Apple
12,Dove
13,Citrus
* Sudden checkpoint," * Leftover checkpoint note 1"," * Leftover checkpoint note N"
16,Citrus
17,Apple
18,Citrus
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
260 次 |
最近记录: |