![在文件列表上运行脚本](https://linux22.com/image/179066/%E5%9C%A8%E6%96%87%E4%BB%B6%E5%88%97%E8%A1%A8%E4%B8%8A%E8%BF%90%E8%A1%8C%E8%84%9A%E6%9C%AC.png)
我有一个脚本,它获取 .vcf 文件,解析该文件并将其写入 .txt
grep -v "#" file.vcf | sed 's/chrM/MT/' | sed 's/chrX/X/' | sed 's/chrY/Y/' | awk '{print $1,$2,$2,$4"/"$5,"+"}' | sed 's/chr//g' > vcf_output.txt
我有 27 个.vcf
文件,我想在其中同时运行此脚本,并将每个文件的输出.vcf
按.txt
该文件的名称写入.vcf
我在谷歌中找到了这个,但运行后没有任何反应
for f in *.vcf; do
script "$f" > "${f%.*}.txt"
done
我采用了如下所示
for f in *.vcf; do
grep -v "#" | sed 's/chrM/MT/' | sed 's/chrX/X/' | sed 's/chrY/Y/' | awk '{print $1,$2,$2,$4"/"$5,"+"}' | sed 's/chr//g' "$f" > "${f%.*}.txt"
done
我也尝试过
(base) loan-mac-13:Pre_Treatment fi1d18$ find -type f -name "*.vcf" | xargs grep -v "#" | sed 's/chrM/MT/' | sed 's/chrX/X/' | sed 's/chrY/Y/' | awk '{print $1,$2,$2,$4"/"$5,"+"}' | sed 's/chr//g' "$f" > "${f%.*}.txt"
find: illegal option -- t
usage: find [-H | -L | -P] [-EXdsx] [-f path] path ... [expression]
find [-H | -L | -P] [-EXdsx] -f path [path ...] [expression]
sed: : No such file or directory
(base) loan-mac-13:Pre_Treatment fi1d18$
我怎样才能推动它为我工作?
答案1
您将script "$f"
google 输出转换为shell 循环脚本中的grep -v "#"
(即缺少),然后您在脚本中的错误位置使用它而不是使用它。"$f"
"$f"
{}
xargs
无论如何,当您使用 awk 时,您永远不需要在管道中使用一堆 sed 和 grep。您没有提供任何示例输入/输出,因此以下 awk 脚本只是现有管道的直接翻译,可能有更好的方法来编写它,但是这个 awk 脚本就是您所需要的,没有 shell 循环或其他任何内容:
awk '
FNR == 1 {
close(out)
out = FILENAME
sub(/\.vcf$/,".txt",out)
}
!/#/ {
sub(/chrM/,"MT")
sub(/chrX/,"X")
sub(/chrY/,"Y")
$0 = $1 OFS $2 OFS $2 OFS $4 "/" $5 OFS "+"
gsub(/chr/,"")
print > out
}
' *.vcf
如果您想像使用 grep+seds+awk 管道那样将其塞入更少的行中,则可以在所有想要删除的换行符处使用分号,除了每个之后{
,例如:
awk 'FNR==1{close(out); out=FILENAME; sub(/\.vcf$/,".txt",out)} !/#/{sub(/chrM/,"MT"); sub(/chrX/,"X"); sub(/chrY/,"Y"); $0=$1 OFS $2 OFS $2 OFS $4 "/" $5 OFS "+"; gsub(/chr/,""); print > out}' *.vcf
答案2
您可以使用 find 和 xargs 来实现。
查找将列出所有文件。
find -type f -name "*.vcf"
使用 xargs,我们可以对找到的每个文件进行操作。
find -type f -name "*.vcf" | xargs grep -v "#" | sed 's/chrM/MT/' | sed 's/chrX/X/' | sed 's/chrY/Y/' | awk '{print $1,$2,$2,$4"/"$5,"+"}' | sed 's/chr//g' "$f" > "${f%.*}.txt"
应该做这份工作吗?
问候
答案3
在不改变任何流程的情况下,以下内容应该可以工作。请注意,您没有向管道中的第一个命令 grep 输入任何内容。所以什么都没有动。
for f in *.vcf; do
< "$f" grep -v "#" | sed 's/chrM/MT/' | sed 's/chrX/X/' | sed 's/chrY/Y/' | awk '{print $1,$2,$2,$4"/"$5,"+"}' | sed 's/chr//g' > "${f%.*}.txt"
done