des*_*esu 6 text-processing csv-simple
我有一个制表符分隔的列文本,如下所示
A B1 B1 C1
B B2 D2
C C12 C13 C13
D D3 D5 D9
G F2 F2
Run Code Online (Sandbox Code Playgroud)
我怎么能像下面这样转换上表
A B1 C1
B B2 D2
C C12 C13
D D3 D5 D9
G F2
Run Code Online (Sandbox Code Playgroud)
我已经提取了我的真实数据文件,它是一个制表符分隔的文件,我已经尝试过你(Stéphane Chazelas?)发布的命令行它工作正常,但它无法删除最后一列的重复项
A CD274 PDCD1LG2 CD276 PDCD1LG2 CD274
B NEK2 NEK6 NEK10 NEK10 NEKL-4
C TNFAIP3 OTUD7B OTUD7B TNFAIP3 TNFAIP3
D DUSP16 DUSP4 DUSP8 VHP-1 DUSP8
E AGO2 AGO2 AGO2 AGO2 AGO2
Run Code Online (Sandbox Code Playgroud)
输出需要如下
A CD274 CD276 PDCD1LG2
B NEK2 NEK6 NEK10 NEKL-4
C TNFAIP3 OTUD7B
D DUSP16 DUSP4 DUSP8 VHP-1
E AGO2
Run Code Online (Sandbox Code Playgroud)
第一组示例数据:
$ awk -vOFS='\t' '{ r=""; delete t; for (i=1;i<=NF;++i) { if (!t[$i]++) { r = r ? r OFS $i : $i } } print r }' file
A B1 C1
B B2 D2
C C12 C13
D D3 D5 D9
G F2
Run Code Online (Sandbox Code Playgroud)
第二组示例数据(相同的awk脚本):
$ awk -vOFS='\t' '{ r=""; delete t; for (i=1;i<=NF;++i) { if (!t[$i]++) { r = r ? r OFS $i : $i } } print r }' file
A CD274 PDCD1LG2 CD276
B NEK2 NEK6 NEK10 NEKL-4
C TNFAIP3 OTUD7B
D DUSP16 DUSP4 DUSP8 VHP-1
E AGO2
Run Code Online (Sandbox Code Playgroud)
该脚本file逐行读取输入文件,并为每一行遍历每个字段,构建输出行r. 如果字段中的值已添加到输出行(由已t用字段值的查找表确定),则该字段将被忽略,否则将被添加。
当输入行的所有字段都被处理后,构建的行被输出。
输出字段分隔符-vOFS='\t'在命令行上设置为 Tab through 。
该awk脚本揭开:
{
r = ""
delete t
for (i = 1; i <= NF; ++i) {
if (!t[$i]++) {
r = r ? r OFS $i : $i
}
}
print r
}
Run Code Online (Sandbox Code Playgroud)
while read -r l; do sed 's/\t/\n/g' <<< "$l" | uniq | paste -s; done < test
Run Code Online (Sandbox Code Playgroud)
或符合 POSIX:
while read -r l; do echo "$l" | tr '\t' '\n' | uniq | paste -s -; done < test
Run Code Online (Sandbox Code Playgroud)
对于文件,test这将逐行Tab用换行符替换所有字符,运行uniq以删除重复项并Tab再次用字符替换换行符。
$ cat test
A B1 B1 C1
B B2 D2
C C12 C13 C13
D D3 D5 D9
G F2 F2
$ while read -r l; do sed 's/\t/\n/g' <<< "$l" | uniq | paste -s; done < test
A B1 C1
B B2 D2
C C12 C13
D D3 D5 D9
G F2
Run Code Online (Sandbox Code Playgroud)
注:该解决方案将不会超过多行,例如,重复的工作C1中
A B1 B1 C1
C1 B B2 D2
Run Code Online (Sandbox Code Playgroud)
也许是这样的:
gawk -vRS='\\s*\\S*' -vORS= '{$0=RT};$1!=prev;{prev=$1}'
Run Code Online (Sandbox Code Playgroud)
该RS=pattern...{$0=RT}招让你处理定义为匹配模式的部分记录。
所以在这里,我们将输入切成<whitespace><non-whitespace> $0记录,<non-whitespace>进入$1(第一个也是唯一的字段)。我们正在打印$1不等于前一个的记录。
在像这样的输入上:
A B1 B1 C1
B B2 D2
C C12 C13 C13
D D3 D5 D9
G F2 F2
Run Code Online (Sandbox Code Playgroud)
记录是:
[A][ B1][ B1][ C1][ B][ B2][ D2][ C][ C12][ C13][ C13][ D][ D3][ D5][ D9][ G][ F2][ F2][ ]
但是不适用于您的第二个示例,请注意它可能会删除一些换行符。