我正在编写一个脚本,它将文件名作为参数,在每行的开头找到一个特定的单词 - 在本例中为单词ATOM - 并打印特定列中的值。
$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
我无法弄清楚三个问题:
答案 0 :(得分:4)
那将是
awk '$1 == "ATOM"' $FILE
使用cut
可以更好地完成该任务:
grep ^ATOM $FILE | cut -c 2-20,38-40
如果你想确保作为脚本的第一个参数传递的文件名以.pdb
结尾:首先,请不要(文件扩展名在UNIX中并不重要),其次如果必须的话,这是一种方式:
"${1%%.pdb}" == "$1" && echo "usage:..." && exit 1
这将获取第一个命令行参数($1
),如果存在,则删除后缀.pdb
,然后将其与原始命令行参数进行比较。如果它们匹配,则它没有后缀,因此程序打印一条用法消息并以状态代码1退出。
答案 1 :(得分:1)
与答案相反,只需一个awk命令即可完成任务。不需要grep或cut或......
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
答案 2 :(得分:0)
您可以在本机bash
中进行所需的所有操作,而不会产生任何子流程:
#!/bin/bash
declare key="ATOM"
declare print_columns=( 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 38 39 40 )
[ ! -f "${1}" ] && echo "File not found." && exit
[ "${1%.pdb}" == "${1}" ] && echo "File is wrong type." && exit
while read -a columns; do
if [ ${columns[0]} == ${key} ]; then
printf "%s " ${key}
for print_column in ${print_columns[@]}; do
printf "%s " ${columns[${print_column}]}
fi
printf "\n"
fi
done < ${1}