2010-10-15 84 views
3

我正在编写一个脚本,它将一个文件名作为参数,在每行的开头找到一个单词 - 在这种情况下,单词ATOM - 并打印特定列中的值。用Awk或Cut打印列?

$FILE=*.pdb * 

if test $# -lt 1 
then 
echo "usage: $0 Enter a .PDB filename" 
exit 
fi 
if test -r $FILE 
then 
grep ^ATOM $FILE | awk '{ print $18 }' | awk '{ print NR $4, "\t" $38,}' 
else 
echo "usage: $FILE must be readable" 
exit 
fi 

我有麻烦搞清楚三个问题:

  1. 如何用awk打印只包含原子作为第一个字线
  2. 如何使用awk来只打印某些列从符合上述标准的行中,具体是第2-20列和第38-40列
  3. 我该如何指出这必须是一个pdb文件? * .PDB *

回答

1

相反的答案用法消息并退出,你的任务可以只用一个awk命令来实现。不需要grep或剪切或...

if [ $# -lt 1 ];then 
echo "usage: $0 Enter a .PDB filename" 
exit 
fi 
FILE="$1" 
case "$FILE" in 
*.pdb) 

if test -r $FILE 
then 
# do for 2-20 assuming whites paces as column separators 
awk '$1=="ATOM" && NF>18 { 
    printf "%s ",$2 
    for(i=3;i<=19;i++){ 
    printf "%s ",$i 
    } 
    printf "%s",$20 
}' "$FILE" 
else 
echo "usage: $FILE must be readable" 
exit 
fi 
;; 
*) exit;; 
esac 
+0

这真棒!谢谢ghostdog。 – Koala 2010-10-16 17:46:13

4
  1. 这将是

    awk '$1 == "ATOM"' $FILE 
    
  2. 这项任务可能是更好的成就与cut

    grep ^ATOM $FILE | cut -c 2-20,38-40 
    
  3. 如果你想确保文件名传递因为脚本的第一个参数以.pdb结尾:首先,请不要(文件扩展名不要在UNIX LLY关系),其次,如果你一定要,这里有一个方法:

    "${1%%.pdb}" == "$1" && echo "usage:..." && exit 1 
    

    这需要第一个命令行参数($1),如果存在去掉后缀.pdb,然后将其比作原始的命令行参数。如果它们匹配,它没有后缀,所以程序打印状态码为1

+0

谢谢大卫!我可以问为什么你说'请不要'参数不仅限于.pdb文件?如果我需要打印的栏目只是在第18-30栏中有条目的类型,我是否应该分别管道化每个栏目? grep^ATOM $ 1 |切-f 18-30 | cut -f 2-20,38-40 – Koala 2010-10-15 19:50:09

+0

@Koala:对于文件名的事情,如果你想在名字以'.txt'结尾的文件上使用你的程序怎么办?或'.csv'?或'.bak'?或者是一个名字没有扩展名的文件?仅仅因为文件名不符合一些任意的约定而使程序失败似乎不是一件愚蠢的事情?当然,这是你的程序,所以你可以让它检查文件名,如果你想要的话,但如果我的经验是任何指导,最终会有一个时候你会想摆脱检查。其他UNIX实用程序(例如'grep'和'awk')不检查文件名;这是有原因的。 – 2010-10-15 20:29:50

+0

至于你的问题的第二部分,关于专栏,我不明白你在问什么。 – 2010-10-15 20:31:15