根据与文件名

时间:2018-02-27 23:34:39

标签: bash loops

我有很多像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

2 个答案:

答案 0 :(得分:1)

通过阅读您的代码,我很困惑,如果这些是输入错误或真正的错误:

  1. 已分配变量file(第5行),但使用$File(第6行)进行调用
  2. 第6行,变量$1被调用,但它没有意义,因为它引用了传递给该脚本的第一个参数,因为你从不进行传递,它给出了null。是$i而不是吗?
  3. 其他问题:

    第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;#34;之间的关系,这令人困惑。你只是将它们混淆在你的例子中,其中," 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
    

答案 1 :(得分:0)

@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