shell 如何在linux下编辑不同目录下的多个文件?

bwleehnv  于 2023-05-23  发布在  Shell
关注(0)|答案(1)|浏览(213)

我在Linux中有几个目录,每个目录都有相同的VCF文件名和相同的初始几行。在这些相同的信息线后面是我需要的数据。我想基本上写一个命令行代码,去这些目录中的每一个,编辑文件,使信息行被删除,我只留下数据。
当我对一个单独的文件进行这种尝试时,我使用以下代码

find . -type f -name "File.vcf" -print0 |
    while IFS= read -r -d '' file; do
        awk 'substr($0,1,3)=="chr"' $file > "$(echo "$file" | cut -d'_' -f2)"_cleaned.vcf
    done

这工作,只给我行,开始与chr这是我想要的。现在我试着加强这一点,用一个命令,我想一石七鸟,并编写了以下代码:

for i in "directory"; do
    cd /user/xxxxxxxx/$i |
        find . -type f -name "File.vcf" -print0 |
        while IFS= read -r -d '' file; do
            awk 'substr($0,1,3)=="chr"' $file > "$(echo "$file" | cut -d'_' -f2)"_cleaned.vcf
        done
    done

当我运行这个时,文件被完全清空,我不明白为什么。我还在努力掌握linux和命令行功能,但如果有人有提示,我将不胜感激。

vi4fp9gy

vi4fp9gy1#

如果没有有关目标文件的名称、位置和内容的详细信息,就很难调试特定问题。但我会重构为

find directories -type f -name "File.vcf" \
    -exec 'for file; do
        grep "^chr" "$file" >"${file%.vcf}_cleaned.vcf"
    done' "$0" {} +

它应该更健壮、更可移植、更有效(尽管我不得不猜测找到的文件名中下划线的位置;也许我猜错了)。
就像William Pursell的评论一样,cd | find既没有用,也不正确。将您要搜索的目录列表直接传递给find;它接受在 predicate 之前要遍历的目录列表。
parameter expansion${file%.vcf}产生变量$file的值,并去掉任何后缀.vcf。后缀表达式可以是一种模式,但如果需要两个下划线之间的文本,则需要两个参数扩展(一个用于删除前缀${file#*_},另一个用于删除后缀${file%_*})。

相关问题