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

时间:2019-11-26 10:19:41

标签: bash

我正在尝试创建一个从文件中获取数字值(多行)并将其按出现顺序添加到另一个文件中的脚本(如果可以的话)。谈到这个,我很环保。可能有某种使用sed的方法,或者甚至省略了文件创建,只是让sed从grep结果中获取值?

Dunno,如果我能更好地解释一下。

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

banana 3
apple 2
peach 1
orange 1

我想要的最终结果是:

external=200100
external=200100
external=200100

很抱歉,如果我对此不太清楚,这是我第一次涉足这一领域,而且我也不是很了解所有事物的正确术语。

想澄清在“ external = 200100”值之间还有其他内容。所以只复制1到1是行不通的。它需要找到每个“ external = 200100”值,并按正确的顺序将grep的结果粘贴到每个“ external = 200100”的末尾。

更清晰的示例可能是:

1 grep的结果:

external=200100101
external=200100102
external=200100104

2我要编辑的文件内部:

100
104

3最终结果

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

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

希望很清楚。

3 个答案:

答案 0 :(得分:0)

重新确定ASK: *从一个文件中读取值列表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

注意:有关向awk提供输入的'grep'命令没有详细信息。最有可能将grep集成到awk中,并消除多余的步骤。为此需要OP输入。

更新2019-11-27

根据Save modifications in place with awk,新版本(> = 4.1)的GNU awk具有(非POSIX标准)“就地”编辑功能

awk -i inlpace ...

我无法对使用它发表评论,因为我通常都会学到这样一种很难的方式:就地编辑实现对错误不友好,并且难以调试设置。由你决定。

通常是安全的选项2

awk 'ORIGINAL CODE HERE' < <(grep ...) SUB=1 input-file > new-file && mv input-file old-file && mv new-file input-file

请注意,重命名取决于awk成功完成。

答案 1 :(得分:0)

已关闭:

# 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// }'

repl上进行了测试。

答案 2 :(得分:0)

如果我理解正确,怎么办:

#!/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"

到目前为止,我对file1的内容没有足够的信息 和您的grep命令。请相应地调整上面的grep行。

我的假设是:

文件1:

foo=100
bar=104

file2(之前):

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

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

file2(之后):

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

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

希望这会有所帮助。