【问题标题】:Change first line based of a name associated with the filename根据与文件名关联的名称更改第一行
【发布时间】:2018-02-27 23:34:39
【问题描述】:

我有很多文本文件,例如 File1、File2 和 File3。 . .文件100

例如,每个文件都有相同的标题

>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

【问题讨论】:

  • 绝对可以,但是可能我速度慢,但是你的问题不是很清楚。这里的用户会帮助你,但不会为你写完整的东西。更好地定义和解释您的需求,然后开始着手处理它。如果您甚至不知道如何开始,我建议您ryanstutorials.net/bash-scripting-tutorial
  • 把评论放在问题里,cmets里的代码很难看懂。
  • 你可以看看这个:stackoverflow.com/questions/9533679/…
  • 如果您在 {1..3} 上查看一次,然后再查看文件,您将处理每个文件 3 次...

标签: bash loops


【解决方案1】:

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

  1. 变量file被赋值(第5行),但用$File调用(第6行)
  2. 第 6 行,变量$1 被调用,但它没有意义,因为它引用了传递给此脚本的第一个参数,因为你从不进行传递,它给出了 null。是$i吗?

其他问题:

第 7 行:无需使用 'g',因为匹配项不超过一个

用单引号或双引号将表达式分割成部分是可以接受的(正如@JohnKugelman 所指出的),但是,要将变量传递给 s/old/new/,除非您在表达式中需要空格字符,否则不必引用表达式.另一方面,如果变量的位置后面有一个单词类字符(字母、数字和下划线“_”),则只需将其括起来即可:

sed -i "1s/7:/${datafile}_7:/" ./File$i.txt

将包含'/'、'*'等特殊符号的变量传递给sed的注意事项:您需要首先使用参数扩展来转义所有这些符号。 (参考外部链接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

【讨论】:

  • @JohnKugelman 感谢您的指出。我还没有测试过这样的东西,(sed手册也没有?)道歉。似乎只是需要将它们全部放在一起而不使用 SPACE,否则后者将被读取为输入文件?
【解决方案2】:

@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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 2011-05-10
    • 1970-01-01
    相关资源
    最近更新 更多