我想将每个文件中第 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 的选项来就地编辑文件。如果该选项在您的实现中不可用,您将需要使用临时文件:s
SCORESUM
"$f"
1
-i
sed
sed
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//' *
事实上,-i
flag 分隔了文件的行寻址(类似于 AWK 中的 FNR 变量)