我有很多 .dat 文件,我想将它们转换为 .sac 文件(一种地震图文件)。我使用 xy2sac 程序转换文件(我没有编写代码),但我必须给转换后的文件一个我选择的新名称。
转换器代码的工作原理如下:
xy2sac filename.dat newfilename.sac
我想要做的是在 xy2sac 程序循环工作时给出我的新文件名。例如我的dat文件名是这样的:
BRGA_KO_disp_post_mij_conv0000_E.dat
BRGA_KO_disp_post_mij_conv0000_E.dat
BRGA_KO_disp_post_mij_conv0000_N.dat
BRGA_KO_disp_post_mij_conv0000_Z.dat
GADA_KO_disp_post_mij_conv0000_E.dat
GADA_KO_disp_post_mij_conv0000_N.dat
GADA_KO_disp_post_mij_conv0000_Z.dat
HYBL_KO_disp_post_mij_conv0000_E.dat
HYBL_KO_disp_post_mij_conv0000_N.dat
HYBL_KO_disp_post_mij_conv0000_Z.dat
ISK_KO_disp_post_mij_conv0000_E.dat
ISK_KO_disp_post_mij_conv0000_N.dat
ISK_KO_disp_post_mij_conv0000_Z.dat
TUZL_KO_disp_post_mij_conv0000_E.dat
TUZL_KO_disp_post_mij_conv0000_N.dat
TUZL_KO_disp_post_mij_conv0000_Z.dat
我想把他们的名字改成:
BRGA_KO__E.sac
BRGA_KO__E.sac
BRGA_KO__N.sac
BRGA_KO__Z.sac
GADA_KO__E.sac
GADA_KO__N.sac
GADA_KO__Z.sac
HYBL_KO__E.sac
HYBL_KO__N.sac
HYBL_KO__Z.sac
ISK_KO__E.sac
ISK_KO__N.sac
ISK_KO__Z.sac
TUZL_KO__E.sac
TUZL_KO__N.sac
TUZL_KO__Z.sac
所以我想选择 .dat 之前的前 8 个字符和最后一个字符。
我怎样才能做到这一点?
我使用了这个循环,但它不起作用,最终得到了 .dat 文件扩展名。
foreach file (`ls *.dat*`)
xy2sac *.dat *.sac << END
END
end
提前致谢。
答案1
如果您确实无法更改为更理智的 shell,那么在 中csh
,您可以使用:s
修饰符在变量内进行字符串替换
前任。
#!/bin/csh -f
foreach file ( *.dat )
echo xy2sac $file $file:s/disp_post_mij_conv0000//:s/.dat/.sac/
end
echo
一旦您确信文件名正确,请删除
答案2
警告:我没有意识到您正在使用 csh,所以我的答案仅适用于 bash。如果这不是一个选择,其他答案提供了可用的解决方案。
您可以将=~
运算符与BASH_REMATCH
数组一起使用来匹配文件名的部分内容并将它们组合成新文件名:
#!/bin/bash
for file in *.dat
do
if [[ $file =~ ([A-Z]+_[A-Z]+_).*(..)\.dat ]]
then
xy2sac $file ${BASH_REMATCH[1]}${BASH_REMATCH[2]}.dac
fi
done
顺便说一句,您应该确保您的要求和示例匹配,这样我们就不必猜测您的实际含义,目前还不清楚您是否确实需要将空的此处文档输入到命令中。我已经构建了代码来匹配您的示例,但显然要匹配的第一个部分并不总是 8 个字符,并且您的意思是 .dat 之前的最后两个字符(包括_
,)而不仅仅是最后一个。
答案3
一个建议:使用awk轻松剪切“_”和“.”并轻松访问您想要构建新文件名的部分
如果你是当然所有 *.dat 文件都具有您提到的确切结构(即,其中没有空格,始终有 6 个“_”,只有 1 个“.”等):
# solution with awk, which can easily define fields using a regex
# (here: "[_.]" so that either 1 "_" or 1 "." separates one field from the next)
# awk will check we presented a filename with the correct number of fields, and also
cd /correct/directory || exit 1 # ie, go to the right directory containing your .dat files, or exit
find ./ -name '*.dat' -print \
| awk -F'[_.]' -v nbfield=8 '
( NF != nbfield ) {
print "Error: file " $0 " ignored: does not have the right structure." ;
next;
}
( NF == nbfield ) {
print "converting file: " $0 " ..."
system("echo _remove_echo_when_ok_ xy2sac " $0 " " $1"_"$2"__"$(NF-1)".sac && echo OK || echo ___ko___ ")
}
'
当然,当您认为它正常工作时:将"echo _remove_echo_when_ok_ xy2sac "
(仅显示但不执行 xy2sac)替换为"xy2sac "
(将执行它)