我有一个以文件中的文件名列表开头的脚本。 对于列表中的每个文件,脚本都会尝试
---
,则从同一行获取第4列中的值,然后使用该值从另一个存档文件中刷出缺少的---
值(具有相同的文件名) ,但不同的位置和扩展名)---
。因此,我想要的输出是原始文件,所有---
实例都根据另一列的查找更改为正确的值。
这是我写的脚本:
#!/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)
答案 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来完成这样的任务。编写和调试会更容易。