如何更改多个文件中的列名?

如何更改多个文件中的列名?

我想将每个文件中第 5 列的名称更改为给定目录中所有文件的文件名本身。我的目录中有 250 个文件,列名称以制表符分隔。

目前,所有文件都具有相同的列名称。文件示例met-d-Glucose.txt

                FID IID PHENO CNT 分数和
  3999347013_R01C01 1 -9 21 -0.217178
  3999347013_R01C02 1 -9 21 -0.054835
  3999347013_R02C01 1 -9 21 -0.130287
  3999347013_R02C02 1 -9 21 0.0062288
  3999347013_R03C01 1 -9 21 -0.0933029
  3999347013_R03C02 1 -9 21 0.0434727

我想将第5列的名称更改为文件名。例如,上面指定的示例文件的输出met-d-Glucose.txt将是:

                FID IID PHENO CNT met-d-Glucose.txt
  3999347013_R01C01 1 -9 21 -0.217178
  3999347013_R01C02 1 -9 21 -0.054835
  3999347013_R02C01 1 -9 21 -0.130287
  3999347013_R02C02 1 -9 21 0.0062288
  3999347013_R03C01 1 -9 21 -0.0933029
  3999347013_R03C02 1 -9 21 0.0434727

原始列名始终是 SCORESUM。标题行始终是第一行。第 5 列之后不再有列。 SCRESUM 不会出现在其他地方。

答案1

由于您要替换单个固定字符串,而不会出现无意的重复,因此以下 shell 循环调用 (GNU)sed将起作用:

for f in *.txt; do sed -i '1s/SCORESUM/'"$f"'/' "$f"; done

这将迭代与通配符模式匹配的所有文件*.txt(如果需要更多特异性,则进行调整)并应用 use将模式sed替换为文件名,存储在 shell 变量 中,但仅在文件的第一行(前导) 。它使用GNU 的选项来就地编辑文件。如果该选项在您的实现中不可用,您将需要使用临时文件:sSCORESUM"$f"1-isedsed

for f in *.txt; do sed '1s/SCORESUM/'"$f"'/' "$f" > tmp.txt; mv tmp.txt "$f"; done

请注意,为了使用 shell 变量,单引号sed程序'1s/.../.../'会被中断,并插入双引号 shell 变量引用。

答案2

在 GNU Sed 的帮助下,使用两个单独的命令可以更轻松地完成此操作。
第一个是在每个文件的第二行写下它的名称:

sed -i 2F *

第二个 - 编辑:

sed -i '1!b;N;s/\S*\n//' *

事实上,-iflag 分隔了文件的行寻址(类似于 AWK 中的 FNR 变量)

相关内容