Bash脚本,从文件中获取值并按顺序将其添加到另一个文件中

Bash脚本,从文件中获取值并按顺序将其添加到另一个文件中,bash,Bash,我试图制作一个脚本,从一个文件(多行)中获取数字值,并按外观顺序将所述值添加到另一个文件中(如果有意义的话)。说到这件事,我是个新手。也许有某种方法可以使用sed,或者甚至可以省略文件创建,而只是让sed从grep的结果中获取值 不知道我是否能更好地解释 基本上,我将grep的结果放在一个文件中,例如,结果是: 101 102 104 108 111 等 现在,我想将这些结果分别添加到另一个文件的特定行中,例如: external=200100 external=200100 external=

我试图制作一个脚本,从一个文件(多行)中获取数字值,并按外观顺序将所述值添加到另一个文件中(如果有意义的话)。说到这件事,我是个新手。也许有某种方法可以使用sed,或者甚至可以省略文件创建,而只是让sed从grep的结果中获取值

不知道我是否能更好地解释

基本上,我将grep的结果放在一个文件中,例如,结果是: 101 102 104 108 111 等 现在,我想将这些结果分别添加到另一个文件的特定行中,例如:

external=200100
external=200100
external=200100

我想要的最终结果是:

external=200100101
external=200100102
external=200100104
对不起,如果我对这一点不够清楚,这是我第一次涉足这一领域,而且我真的不知道什么是正确的术语

想要澄清的是,在“外部=200100”值之间还有其他东西。所以仅仅将1复制到1是行不通的。它需要找到每个“external=200100”值,并将grep结果按适当顺序粘贴到每个“external=200100”的末尾

更清楚的例子可能是:

1 grep的结果: 我要编辑的文件的2个内部: 等

3最终结果 等

希望这足够清楚。

重复提问: *读取值val-1、val-2的列表。。。从一个文件 *读取第二个文件,并将val[n]追加到以“external=”开头的行的第n次出现处

值列表是由某个grep命令动态生成的

我认为awk应该能够做这项工作

awk '
!SUB {
   # Read values from file1, store in val array.
   val[i1++] = $0 ;
}

SUB {
  # Append value if needed
  if ( $0 ~ /^external=/ ) $0 = $0 val[i2++]
  print 
  next
}

' <(grep ...) SUB=1 input-file
我无法评论如何使用它,因为我通常很难理解,就地编辑实现对bug不友好,并且创建难以调试的设置。由你决定

选项2通常是安全的

awk 'ORIGINAL CODE HERE' < <(grep ...) SUB=1 input-file > new-file && mv input-file old-file && mv new-file input-file
awk“此处的原始代码”
注意:重命名取决于awk成功完成。

在sed中:

# recreate and pipe the input
cat <<EOF |
[100]
secret=blah
type=blah
dial=blah
external=200100

[104]
secret=blah
type=blah
dial=blah
external=200100
EOF

# the script
sed '
   # remember the part between braces
   /^\[\([0-9]*\)\]$/{
          # hold current line, we are going to change it
          h
      # remove from the line the [ ]
      s//\1/
      # switch hold and pattern space
            x
   }
   # add it to the end of the line we want to
   /^external=[0-9]*$/{
       # grab hold space
       G
       # remove the newline appended by sed when grabing
       s/\n//
   }
'
更好的一行:

sed '/^\[\([0-9]*\)\]$/{ h;s//\1/;x }; /^external=[0-9]*$/{ G;s/\n// }'

测试日期。

如果我理解正确,那么:

#!/bin/bash

mapfile -t values < <(grep -oE "[0-9]+" "file1")
# now the array "values" holds (100 104 ..)

mv -f "file2" "file2.bak"
# make a backup of file2
while IFS= read -r line; do
    [[ $line =~ ^external= ]] && line+="${values[$((i++))]}"
    # if the line starts with the pattern "external=" then append
    # the element of array "values" in order
    echo "$line"
done < "file2.bak" > "file2"
文件2(之前):

文件2(之后):


希望这有帮助。

提供输入示例和输出示例。您尝试过什么吗?添加了一些示例。我尝试了sed和awk的一些功能,但我还没有真正掌握所有选项,因此没有什么真正起作用。您可以使用纯Bash来实现这一点。只要逐行读文件就行了。在
=
处拆分,然后合并字符串。它可以从文件2读取并粘贴到文件1中,也可以从grep读取并粘贴到文件1中(不知道是否可以直接从grep执行,无论哪种方式都可以)。也很抱歉,我应该把文件名放在哪里?从未使用过此类命令。修改了示例代码以显式引用输入文件。另请注意,该命令只生成到stdout的输出。你需要替换原始文件吗?嗯,我想它应该编辑/替换原始文件。我想从另一个文件中添加一些东西。嗯,不完全是我想的,输入100个数字似乎不是一个好主意。此外,输出应保存到文件中,而不仅仅是打印。除非我遗漏了一些东西,这可能是因为我对此一无所知。请了解shell重定向以及如何将命令输出保存到文件。如果您有GNU
sed
实现,那么它有
-i
开关以允许就地编辑文件。我不明白输入100个数字似乎不是一个好的部分,你为什么要输入数字,在哪里输入?等等,也许我完全误解了你的问题。grep:
结果与文件的相关性如何?它们不是从
[104]
行生成的吗?因此,grep:
结果中的numebr与我要编辑的文件的
[]
内部
中存储的数字不同:
文件?我被“cat>>EOF”弄糊涂了,这不要求我输入吗?实际上,grep的结果是从另一行生成的。这只是一个例子,我需要浏览的文件中有几十个/数百个数字需要更改。。它是猫
awk 'ORIGINAL CODE HERE' < <(grep ...) SUB=1 input-file > new-file && mv input-file old-file && mv new-file input-file
# recreate and pipe the input
cat <<EOF |
[100]
secret=blah
type=blah
dial=blah
external=200100

[104]
secret=blah
type=blah
dial=blah
external=200100
EOF

# the script
sed '
   # remember the part between braces
   /^\[\([0-9]*\)\]$/{
          # hold current line, we are going to change it
          h
      # remove from the line the [ ]
      s//\1/
      # switch hold and pattern space
            x
   }
   # add it to the end of the line we want to
   /^external=[0-9]*$/{
       # grab hold space
       G
       # remove the newline appended by sed when grabing
       s/\n//
   }
'
[100]
secret=blah
type=blah
dial=blah
external=200100100

[104]
secret=blah
type=blah
dial=blah
external=200100104
sed '/^\[\([0-9]*\)\]$/{ h;s//\1/;x }; /^external=[0-9]*$/{ G;s/\n// }'
#!/bin/bash

mapfile -t values < <(grep -oE "[0-9]+" "file1")
# now the array "values" holds (100 104 ..)

mv -f "file2" "file2.bak"
# make a backup of file2
while IFS= read -r line; do
    [[ $line =~ ^external= ]] && line+="${values[$((i++))]}"
    # if the line starts with the pattern "external=" then append
    # the element of array "values" in order
    echo "$line"
done < "file2.bak" > "file2"
foo=100
bar=104
[100]
secret=blah
type=blah
dial=blah
external=200100

[104]
secret=blah blah
type=blah blah
dial=blah blah
external=200100
[100]
secret=blah
type=blah
dial=blah
external=200100100

[104]
secret=blah blah
type=blah blah
dial=blah blah
external=200100104