我有很多像File1,File2和File3这样的文本文件。 。 。 File100
例如,每个文件都有相同的标题
>7:1234-5678
line 2
line 3
.
.
比方说,每个文件对应一个人
File1=Juan
File2=Pedro
File3=Carlos
我想要做的是将每个人的名字添加到每个文件的第一行。这样的事情:
>Juan_7:1234-5678
line 2
line 3
.
.
换句话说:我有几个文本文件(File1 ... File100),我有一个带有这些文件名的密钥文件和它们所属的名称(个人)。我想把这些名字(个人)放在每个文件的第一行。现在更有意义吗?
我尝试过以下代码,但可能是错误的。
#!/bin/bash
File1="Juan"; File2="Pedro"; File3="Carlos"
for i in {1..3}; do
for file in ./*.txt; do
eval datafile="\$File$i"
sed -i -e '1 s/7:/'"$datafile"'_7:/g' ./File"$1".txt
done
done
通过阅读你的代码我很困惑,如果这些是输入错误或真正的错误:
file
(第5行),但用$File
调用(第6行)$1
被调用,但它没有意义,因为它引用传递给该脚本的第一个参数,因为你从不进行传递,它给出null。是$i
而不是?其他问题:
第7行:不需要使用'g',因为只有一个匹配
使用单引号或双引号将表达式切割成部分是可以接受的(如@JohnKugelman所述),但是,要将变量传递给s / old / new /,除非在表达式中需要SPACE字符,否则不必引用表达式。另一方面,如果在变量的位置后面有一个单词类字符(字母,数字和下划线“_”),只需拥抱它:
sed -i "1s/7:/${datafile}_7:/" ./File$i.txt
注意将包含特殊符号(如'/','*'等)的变量传递给sed:您需要首先使用参数扩展来转义所有这些符号。 (C.f.外部链接Passing variables which contain special characters to sed和Bash手册Parameter expansion)
关于逻辑结构的问题:
正如@ Nic3500所说的那样。第一个for
循环在i
上包含3个循环;第二个for
循环在目录中的n个文件中包含n个循环 - 总共3 * n个循环。但是你的操作只需要n。
这是令人困惑的,因为你没有说File $ i.txt和值“Juan”之间的关系是什么。你只是在你的例子中混淆了它们,其中,“File1”是一个变量,但同时文件名为“File1.txt”。如果你真的有一组这样的变量(变量名=文件名),你可以:
for i in {1..3}; do
sed -i "1s/7:/$(eval echo \$File$i)_7:/" ./File$i.txt
done
与使用动态变量名称的脚本相同。
但是使用变量作为变量的名称并且我个人不推荐这真的令人沮丧。相反,我认为使用数组更好:
NAME=(Juan Pedro Carlos); # Or other ways to assign this array
for((i=0;i<${#NAME[@]};i++)); do
sed -i "1s/7:/${NAME[$i]}_7:/" ./File$(($i+1)).txt
done
@LDecem,谢谢你的回答,我必须说你指出的很多东西都在我头上。我实际上发现了一个脚本,可以实现我真正想要的。我不知道语法是否正确但是它运行良好。关于名称,我只是把它们作为一个例子,但它们实际上是其他类型的字符串。
我所说的代码是:
File1=TLRP1; File2=TLRP4; File3=TLRP5
for i in {1..3}; do
for file in ./File"$i"_data.txt; do
eval datafile="\$File$i"
sed -i -e '1 s/7:/'"$datafile"'_7:/g' ./File"$i"_data.txt
done
done