使用 Awk 或 Cut 打印列?

发布于 2024-09-27 12:15:53 字数 489 浏览 4 评论 0原文

我正在编写一个脚本,它将采用文件名作为参数,在每行的开头查找一个特定的单词(在本例中为单词 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

我无法解决三个问题:

  1. 如何使用 awk 只打印包含 ATOM 作为第一个单词的行
  2. 如何使用 awk 只打印符合上述条件的行中的某些列,特别是第 2-20 和 38 列-40
  3. 如何指示这必须是 pdb 文件? *.pdb *

I'm writing a script that will take a filename as an argument, find a word a specific word at the beginning of each line - the word ATOM, in this case - and print the values from specific columns.

$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

I'm having trouble figuring out three problems:

  1. How to use awk to print only lines that contain ATOM as the first word
  2. How to use awk to print only certain columns from the rows that match the above criteria, specifically columns 2-20 and 38-40
  3. How can I indicate this must be a pdb file? *.pdb *

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤千羽 2024-10-04 12:15:54
  1. 那就是

    awk '$1 == "ATOM"' $FILE
    
  2. 使用cut可能可以更好地完成该任务:

    <前><代码>grep ^ATOM $FILE |切-c 2-20,38-40

  3. 如果您想确保作为第一个参数传递给脚本的文件名以 .pdb 结尾:首先,请不要这样做(文件扩展名在 UNIX 中并不重要),其次,如果您必须这样做,这里有一个方法:

    "${1%%.pdb}" == "$1" && echo“用法:...”&& 1号出口
    

    这采用第一个命令行参数 ($1),删除后缀 .pdb(如果存在),然后将其与原始命令行参数进行比较。如果它们匹配,则它没有后缀,因此程序会打印一条使用消息并以状态代码 1 退出。

  1. That would be

    awk '$1 == "ATOM"' $FILE
    
  2. That task is probably better accomplished with cut:

    grep ^ATOM $FILE | cut -c 2-20,38-40
    
  3. If you want to ensure that the filename passed as the first argument to your script ends with .pdb: first, please don't (file extensions don't really matter in UNIX), and secondly, if you must, here's one way:

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

    This takes the first command-line argument ($1), strips the suffix .pdb if it exists, and then compares it to the original command-line argument. If they match, it didn't have the suffix, so the program prints a usage message and exits with status code 1.

2024-10-04 12:15:54

与答案相反,您的任务只需一个 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

Contrary to the answer, your task can be accomplished with just one awk command. No need grep or cut or ...

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
不乱于心 2024-10-04 12:15:54

您可以在本机 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}

You can do everything you need in native bash without spawning any sub-processes:

#!/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}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文