首页 > 解决方案 > 需要文件中的数字列。然后每个数字必须通过查找/替换 sed 转到另一个文件。问题:最终文件都有相同的编号

问题描述

我一直在使用 Bash 和 Awk 脚本来组织许多大文件。这里的患者建议非常有帮助。我有一个新问题。

  1. 我有许多相同的文件,称为“输入”。它们包含数字和字符串。目录“Parent”包含子目录(Daughter1、Daughter2、Daughter3 等)。每个子目录包含一个“输入”文件。

  2. 一个单独的文件“numbers.txt”只包含一列数字。列中的数字/行与父/子(i)/输入文​​件一样多。简短的例子:

    10.987  
    10.654321  
    13.3210
    
  3. 我想将每个输入文件中的一个数字更改为 numbers.txt 中的一个新数字。Daughter1/input 处的文件应更改为 numbers.txt 第一行中的数字。Daughter2/input 应该改成 numbers.txt 第二行的数字,以此类推。

到目前为止,我发现下面的这个 sed(这里是“gsed”;我是 OS X Sierra 用户)表达式是可靠的,如果可能的话,我想继续使用它:

#!/bin/bash

old_number="12.345678" # This number is in all "input" files. 
new_number="87.654321"

find Parent/Daughter* -type f -exec gsed -i -e "s/${old_number}/${new_number}/g" {} +

问题是我无法${new_number}在上面的代码中进行修改,以便它正确使用“numbers.txt”(上面的2)中的数字。这是几乎可以工作的东西。它确实更改了“输入”文件(上面的 1)中的旧数字,但所有输入文件现在都包含10.987(第一个数字)。每个输入文件都应该有一个不同的编号。

i=0
while read line
do
    arr[$i]="$line"
    find Parent/Daughter* -type f -exec gsed -i -e "s/${old_number}/${arr[i]}/g" {} +
    i=$((i+1))
done < numbers.txt

如果这个问题太长或不清楚,我很乐意修改它。谢谢你。


更新 jas 的建议(请参阅我的问题下方的评论)让我大部分时间都在那里。谢谢你,贾斯!我需要弄清楚如何识别我拥有的父/子/输入文件的数量,并在我到达最后一个时停止循环,但除此之外,这运作良好。

i=0
while read line
do
    arr[$i]="$line"
    find Parent/Daughter${i} -type f -exec gsed -i -e "s/${old_number}/${arr[i]}/g" {} +
    i=$((i+1))
done < numbers.txt

标签: bashfileawkreplaceio

解决方案


由于每次循环您只想更新一个文件,并且您确切知道是哪个文件,因此您可以直接运行 sed 而无需查找。(另外,我认为没有必要使用数组变量,除非你以后需要它):

i=1
while read line
do
    gsed -i -e "s/${old_number}/${line}/g" Daughter${i}/input
    i=$((i+1))
done < numbers.txt

这假设您在 numbers.txt 文件中拥有用于更新 Daughter*/input 文件的所有行并且只有尽可能多的行。


推荐阅读