0

我有一个以文件中的文件名列表开头的脚本。对于列表中的每个文件,脚本会尝试

  • 查看文件中的一行
  • 如果该行中的第 2 列---然后从同一行获取第 4 列中的值,则使用该---值从另一个存档文件中 grep 缺失值(具有相同的文件名,但位置和扩展名不同)
  • 然后---用 grepped 值替换。

因此,我想要的输出是原始文件,所有实例都---根据另一列的查找更改为正确的值。

这是我为此编写的脚本:

#!/bin/bash
# process the files in the list
for fname in $mylist ; do
    for line in $fname ; do 
    name=$(echo $fname | awk -F"/" '{print $9}' | sed 's:.ext::g'); #getbasename to help find archive file
    dash=$(awk < "$line" '{print $2}');  #get col2 of the line (may have the "---" missing value")
    loca=$(awk < "$line" '{print $4}');  #col 4 for grepping

        if [$dash -eq "---"]; then   
            ID=$(grep -F -w "$loca" /path/archiveFiles/$name | awk '{print $2}'); #find the missing value in the relevant archive file, using $loca as the lookup key
            fixed=$(awk  -v snpID="$ID" '{OFS="\t"} {print $1,ID, $3, $4}' "$fline");
            echo "$fixed" ;
        else echo "$line" ;
        fi 
    done  >>/path/correctedFiles/$name.ext &

done
wait

该脚本当前给出 sterror 说“第 XX 行:IDNNNN:找不到命令”第 XX 行在脚本中不存在(实际上它是脚本中的最后一行并且是空的)IDNNNN 是我试图 grep 的缺失值之一从存档文件。谁能帮我解决这个输出?谢谢

:edited 脚本更好地解释 grep ;再次编辑示例文件和错误消息:mylist:

> path/dir/file_1_17.03s.07.ext path/dir/file_1_2.51p.12.ext
> path/dir/file_2_112.07.ext path/dir/file_2_155.07.ext
> path/dir/file_13_1.5.12-13.ext

file_1_17.03s.07.ext 的内容(所有文件格式相同)

>     1 ID45    0   KEY7
>     1 ID46    0   KEY45
>     1 --- 0   KEY501
>     1 ID48    0   KEY6

从中 grep 缺失数据的存档文件的内容,即文件 file_1_17.03s.07.ext,查看 /path/archiveFiles/file_1_17.03s.07.arc

X1    ID45    KEY7
X2    ID46    KEY45
X3    ID47    KEY501
X4    ID48    KEY6

我上面要做的是更正列表中的每个文件,使用相关存档文件中的 KEY 列,以便 file_1_17.03s.07.ext 的内容变为

1 ID45    0   KEY7
1 ID46    0   KEY45
1 ID47    0   KEY501
1 ID48    0   KEY6

运行我的脚本时出错;

> /var/spool/stuff: line 53: ID45: command not found /var/spool/stuff:
> line 53: ID46: command not found (and so on)

运行建议的更正错误;

/var/spool/stuff: line 53: file_1_17.03s.07: command not found
/var/spool/stuff: line 53: file_1_2.51p.12.: command not found (and so on)
4

1 回答 1

0

这是一个可能有效的版本(尚未测试)。这是我用来测试的。

创建测试环境:

mkdir out
mkdir archive
echo -e "one\ttwo\tthree\tfour\none\t---\tthree\tfour" > test.ext
echo -e "newone\tnewtwo\tnewthree\tfour" > archive/test.arc
rm out/test.ext

以下脚本有效。

#!/bin/bash

mylist="test.ext"
path_archive="./archive/"
path_out="./out/"

process_line () {
  line=$1
  name=$2
  set -- $line

  if [ "$2" == "---" ] ; then
    ID=$(grep -F -w "$4" ${path_archive}/${name}.arc | awk '{print $2}')
    echo -e "$1\t$ID\t$3\t$4"
  else
    echo "$line"
  fi
}

# process the files in the list
for fname in `cat $mylist` ; do
  echo processing $fname

  name=`basename $fname .ext`
  cat $fname | while read line ; do
    process_line "$line" "$name" >> $path_out/$name.ext
  done 
done

set -- $line是一个 bash 的事情。这会将位置参数 ( $1, $2, ...) 设置为提供给 的任何参数set --。不带参数,set --取消设置位置参数。考虑以下示例:

:~$ echo $1

:~$ set -- foo
:-$ echo $1
foo
:-$ set -- bar
:-$ echo $1
bar

如果文件名中包含空格,上述for fname in `cat $mylist`; do方法将不起作用。$mylist如果是这种情况,并且每一行中只有一个文件名,则应cat $mylist | while read fname ; do改为$fname使用双引号 ( "$fname")。

输出:

$ cat test.ext
one two three   four
one --- three   four
$ cat out/test.ext
one two three   four
one newtwo  three   four

总而言之,我宁愿使用 Perl 或 Python 来完成这样的任务。编写和调试会容易得多。

于 2013-07-02T08:16:36.003 回答