我有一个文件如下:
name1 name2 name3 name4
AA BB BB CC
AA AA BB CC
AA CC BB CC
AA DD BB DD
AA DD BB AA
第1列和第3列本身具有相同的字符串。如果案例如上所述,我希望删除整个列,但保留标题。所以最终文件会变成这样的东西。
name2 name4
BB CC
AA CC
CC CC
DD DD
DD AA
有没有办法用grep或awk这样做?非常感谢!
答案 0 :(得分:1)
这在性能方面并不是完全最优的,但确实使用了awk
,它确实适用于您的示例输入:
file=$1
header=$(head -1 "$file")
i=1
goodcols=""
for colname in $header; do
count=$(awk "NR>1 {print \$$i}" "$file" | sort -u | wc -l)
if [ $count -gt 1 ]; then
if [ -z "$goodcols" ]; then
goodcols="\$$i"
else
goodcols="$goodcols, \$$i"
fi
fi
i=$((i+1))
done
awk "{print $goodcols}" "$file"
答案 1 :(得分:0)
如果您的意图是打印整个文件,如果任何一行中的第1列和第3列中的任何一个值不同,并且只打印第2列和第4列,其中每个行在列中具有相同的值1和3,以下脚本将执行此操作:
same=$(awk 'BEGIN{same=1}NR==1{next}$1!=$3{same=0;exit}{}END{print same}' qq.in)
if [[ $same -eq 1 ]] ; then
awk '{print $2" "$4}' qq.in
else
cat qq.in
fi
如果所有行(当然不是标题)具有相同的awk
值,则第一个1
输出column1/3
。否则输出0
。
然后,您只需使用它来过滤列,或按原样输出文件。
相反,如果第1列中的所有值都相同且第3列中的所有值相同(根据您的测试数据),您只想删除第1列和第3列,请将第一行更改为:
allsame=$(awk 'BEGIN{allsame=1}NR==1{next}NR==2{val1=$1;val3=$3;next}$1!=val1||$3!=val3{allsame=0;exit}{}END{print allsame}' qq.in)
答案 2 :(得分:0)
UNIX shell只是一个可以从中调用UNIX工具的环境。用于一般文本操作的UNIX工具是awk,所以只需使用它:
$ cat tst.awk
{
for (col=1; col<=NF; col++) {
val[NR,col] = $col
if ( (NR>1) && (!seen[col,$col]++) ) {
cnt[col]++
}
}
}
END {
for (row=1; row<=NR; row++) {
ofs = ""
for (col=1; col<=NF; col++) {
if (cnt[col] != 1) {
printf "%s%s", ofs, val[row,col]
ofs = OFS
}
}
print ""
}
}
$ awk -f tst.awk file
name2 name4
BB CC
AA CC
CC CC
DD DD
DD AA