【问题标题】:substituting a string with a variable string用变量字符串替换字符串
【发布时间】:2020-07-09 06:45:28
【问题描述】:

我有两个目录,S 和 T,每个目录有 150 个文件。文件名相同,例如,如果 S 包含 file1、file2、...、file150,则 T 也包含 file1、file2、...、file150。 S 中的每个文件都包含以下代码:

<a href="index.php">Home</a>  &rarr; <a href="page1.php">Page 1</a> 
&rarr;  NAME1  <a href="A.php"> &rarr Previous</a> <a href="B.php">Next  &rarr </a>

在所有 150 个文件中,除了 NAME1 之外,所有文件都是相同的,即 file2 的 NAME2,file3 的 NAME3,等等。

T 中的每个文件都包含以下代码:

<a href="index.php">Home</a>  &rarr; <a href="page1.php">Page 1</a> 
&rarr;  STRING1  <a href="X1.php"> &rarr Previous</a> <a href="Y1.php">Next  &rarr </a>

其中 STRING1 表示 file1,STRING2 表示 file2 等是(相当长的)其他代码的字符串,每个文件都会更改,X1、Y1 对于每个文件也不同,分别是 X2、Y2 表示 file2、X3、Y3对于file3等。

我想编写一个 shell 脚本,将 T/file1 中的字符串 X1、Y1 替换为 S/file1 中的字符串 A、B,将 T/file2 中的 X2、Y2 替换为 S 中的字符串 A、B /file2 等等。我正在使用 Mac 或 Ubuntu 计算机上的终端。我已经在网上和这个论坛上进行了搜索,并尝试使用 sed 和 awk 但我无法正常工作。 感谢您提供任何帮助或建议。

我将举一个只有两个文件而不是 150 个文件的示例。 假设我准备好了脚本。在我执行脚本之前,目录 S 有文件 file1 的内容

N1 A B

和文件 file2 的内容

N2 A B

而目录 T 有文件 file1 的内容

S1 X1 Y1

和文件 file2 的内容

S2 X2 Y2

执行脚本后,S 有文件 file1 的内容

N1 X1 Y1

和文件 file2 的内容

N2 X2 Y2

而目录 T 没有改变。

我希望在我运行脚本时对所有 150 个文件都执行此操作。

【问题讨论】:

  • 如果您提出minimal reproducible example 并发布,您可能会收到更多回复。见How to Ask。现在您正在讨论不同目录中的大量文件,每个文件中都有多个移动部分,以及带有一堆看起来很复杂的文本的示例,所以 YMMV。
  • 从你的问题来看,你为什么不直接复制 T 并将其重命名为 S?那么输出看起来是相同的......
  • @Ed Morton 感谢您的建议。我添加了一个示例,以防只有两个文件。
  • @Daemon Painter 实际上我在描述问题时犯了一个错误,您的评论让我意识到了这一点。目录 T 中还有其他代码与目录 S 不同,我现在已经纠正了错误。
  • 如果问题是如何根据第二个文件中的文本转换 1 个文件,而不是作为示例并在这两个文件中包含复杂的文本。如果问题是如何转换多个文件,那么将其作为您的示例,但使用简单的输入文件。只需创建您的示例以最好地展示您需要帮助的问题。

标签: string awk sed substitution


【解决方案1】:

这样的事情可能是最简单的:

for path in S/*; do
    file="${path#*/}"
    awk '
        NR==FNR { $1=""; vals[NR]=$0; next }
        { print $1 vals[FNR] }
    ' "T/$file" "S/$file" > tmp &&
    mv tmp "S/$file"
done

对于像您发布的最后一个示例这样微不足道的事情,您不需要像那样使用 awk,但从您的原始示例看来,您需要进行一些更复杂的处理,因此我展示了将 awk 脚本放入过程。

【讨论】:

  • 我刚试了一下,效果很神奇。事实上对我来说就是这样,因为我对它几乎一无所知:你能突出它的主要步骤吗?我特别惊讶的是,我的原始代码实际上比我在第一个示例中发布的代码要复杂得多,但这个脚本完全符合我的要求。我想了解它如何从正确的位置准确提取 X1 和 Y1。
  • NR==FNR 是在读取第一个输入文件时为真的条件(请参阅 awk 手册页中的 NR 和 FNR)。我所做的只是从第一个文件的每一行中删除第一个字段 ($1),并将该行的其余部分保存在由行号索引的 vals[] 数组中。然后在读取第二个文件时,我打印每行的第一个字段加上我之前从第一个文件中保存的 vals[line number] 内容。
  • 但是,如果您的问题真的是关于如何从一个文件中提取特定字段以在另一个文件中使用,那么这就是您应该发布的问题,因为该焦点被有关处理多个不同文件的信息所掩盖不同的目录。
  • 感谢您的解释。我是否理解脚本能够找到“X1.php”,因为 $1="" ?然后它找到“Y1.php”?因为下一个?我之所以包含有关拥有 150 个文件的信息,是因为只有一个文件可以手动完成,我想解释为什么我需要一个脚本。但我现在意识到这涉及到两件不同的事情,而且我已经知道如何做第二件,所以我应该只问第一件。
  • 我发布的 awk 脚本并非旨在解决将您的特定值从您的格式文件复制到另一个文件的问题,它是关于如何跨目录操作多个同名文件。请发布一个新问题,该问题只是关于如何将 fileA 中的文本替换为 fileB 中的文本,并包含两个文件的实际内容。保持清晰,简单,仅关于那个,不要在目录 x 和目录 y 中添加关于文件这个和文件那个的所有额外无关信息,等等。
猜你喜欢
  • 2011-09-29
  • 2013-02-16
  • 2014-12-11
  • 1970-01-01
  • 2017-06-21
  • 1970-01-01
  • 2018-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多