4

我有一个格式如下的文件:

text   number   number   A;A;A;A;A;A
text   number   number   B
text   number   number   C;C;C;C;D;C;C;C;C

我想要做的是删除第四列中条目的所有重复项,以结束:

text   number   number   A
text   number   number   B
text   number   number   C;D

我更喜欢使用 bash 脚本作为解决方案,以适应我正在对该文件进行的其他文本操作的管道。

谢谢!

4

4 回答 4

3

可以使用awk. 使用 ; 将字段 4 拆分为数组 第一的

awk '{delete z; d=""; split($4,arr,";");for (k in arr) z[arr[k]]=k; for (l in z) d=d";"l; print($1,$2,$3,substr(d, 2))}' file_name
于 2012-11-02T19:13:34.263 回答
2

这可能对您有用(GNU sed):

sed 's/.*\s/&\n/;h;s/.*\n//;:a;s/\(\([^;]\).*\);\2/\1/;ta;H;g;s/\n.*\n//' file
于 2012-11-02T19:09:42.440 回答
2

假设制表符分隔的输入,您可以使用 GNU 并行执行此操作:

parallel -C '\t' c4='$(echo {4} | tr ";" "\n" | sort -u | head -c-1 | tr "\n" ";");' \
                 echo -e '"{1}\t{2}\t{3}\t$c4"' :::: infile

输出:

text    number  number  A
text    number  number  B
text    number  number  C;D
于 2012-11-03T23:46:40.777 回答
1

这也可能有效

awk -F";" '{
              delete words
              match($1,/[[:alpha:]]$/)
              words[substr($1,RSTART,RLENGTH)]++
              printf "%s",$1
              for (i=2;i<=NF;i++){
                if (!words[$i]++) printf ";%s",$i
              }
              printf "\n"
           }' file

笔记:

  1. 由于;用作字段分隔符,因此之前有多少列(或用于这些列的分隔符)并不重要A;A;A;A;A;A

  2. /[[:alpha:]]$/可以替换/[^[:space:]]+$/为匹配多个非空格字符而不是单个字母。

  3. if (!words[$i]++) printf ";%s",$i如果列/字符不作为关联数组的键存在,则打印列/字符words,即如果words[$i]为 0。

于 2012-11-03T10:37:55.523 回答