在BASH中嵌套for / If循环错误,输出无效

时间:2013-07-02 07:38:46

标签: bash

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

  • 查看文件中的一行
  • 如果该行中的第2列为---,则从同一行获取第4列中的值,然后使用该值从另一个存档文件中刷出缺少的---值(具有相同的文件名) ,但不同的位置和扩展名)
  • 然后用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

该脚本目前提供的是“XX行:IDNNNN:未找到命令” 第XX行不存在于脚本中(实际上它是脚本中的最后一行并且为空) IDNNNN是我试图从存档文件中grep的缺失值之一。 任何人都可以帮我解决这个问题吗?谢谢

:编辑脚本来解释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

要从中查找缺失数据的存档文件的内容,即文件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)

1 个答案:

答案 0 :(得分: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是一种抨击。这会将位置参数($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来完成这样的任务。编写和调试会更容易。