【问题标题】:How to use a while loop to read text consecutively from text file and output text parameters into a command如何使用while循环从文本文件中连续读取文本并将文本参数输出到命令中
【发布时间】:2017-08-14 00:08:52
【问题描述】:

我们正在尝试制作一个读取hosts.txt 文件和infile 的报告。当它在包含文本host1 的行上方找到第一个host1 时,它应该创建一个标题,然后在它刚刚创建的标题行下方放置一个新行,保持所有其他文本不变,并继续为host1-30 执行此操作。

目前我们在函数中使用单个 grepsed 命令来执行此操作。我们在第一个匹配项上方添加一些标题文本,然后在该标题文本下添加一个空行。在示例中,我们仅显示 2 个主机 host1host2

我们正在寻找一种方法来使用 while 循环而不是单个 sed/grep 命令来执行此操作。主机按顺序显示在 infile 中,因此可以在 while 循环中从 hosts.txt 顺序读取。

这是使用sedgrep 命令手动执行此操作的示例。我们有一个输入文件infilegrep/sed 语句与 host1host2 匹配,并在上方输入标题,在下方输入空行。

infile 文件:所有文本都是文字 - 随机文本是完全随机的。 除了找到 host1-30 的那一行之外,永远不会有 [ ]:

1    any-random-text1 [host1][randomo randomp randomr randomc randomu]
2    any-old-random-text2 randome randomiest randomer randomo randomy randomx randomk randoml randomz
1    some-random-text1 [host2][randomo randomp randomr randomc randomu]
2    any-stupid-random-text2 randome randomiest randomer randomo randomy randomx randomk randoml randomz

这是我们的hosts.txt 文件:

hosts.txt file:

host1
host2

我们现在用我们的手册添加一个标题sedgrep - 当前的工作方法:

header="Some Header Text We Need"

header() # I use a function in the example but it can be done without.
{
a=$(grep -n host1 outfile | cut -d : -f 1)
sed $a'i\'"**host1_ - ""$header"'\' outfile > outfile1
b=$(grep -n host2 outfile1 | cut -d : -f 1)
sed $b'i\'"**host2_ - ""$header"'\' outfile1 > outfile2
# we need to add a blank line now
a=$(grep -n -w host1 outfile2 | cut -d : -f 1)
sed $a'i\\' outfile2 > outfile3
b=$(grep -n -w host2 outfile3 | cut -d : -f 1)
sed $b'i\\' outfile3 > outfile4
}

我们的输出文件 outfile4 正是我们所需要的,并且这种方法有效,但我们希望使用 while 循环而不是读取 hosts.txt 来查找上面 grep 命令使用的 host1host2 字符串。 outfile4的内容:

 user@host$ cat outfile4
**host1_ - Some Header Text We Need

1   any-random-text1 [host1][randomo randomp randomr randomc randomu]
2   any-old-random-text2 randome randomiest randomer randomo randomy randomx randomk randoml randomz
**host2_ - Some Header Text We Need

1   some-random-text1 [host2][randomo randomp randomr randomc randomu]
2   any-stupid-random-text2 randome randomiest randomer randomo randomy randomx randomk randoml randomz

相反 - 我们希望能够通过 while 循环来做到这一点。:我试过这个,但它不起作用。

date=`date +%Y%m%d`
hosts=hosts.txt
header="Some Header Text We Need"

addheader()
{
 while read -r LINE; do
   x=$(grep -n "$LINE" outfile | cut -d : -f 1)
   sed $x'i\'""$LINE_"' - ""$header"'\'
 done < hosts.txt > 2
}

addblankline()
{
 while read -r LINE; do
   a=$(grep -n -w $LINE outfile | cut -d : -f 1)
   sed $a'i\\'
 done < hosts.txt > 2
}

我们希望我们的 while 循环读取 hosts.txt 并看起来像 output4 文件的样子:使用我们的单一手册 sedgrep 命令为我们做了什么:

 infile: this should look like outfile4 below:

1   any-random-text1 [host1][randomo randomp randomr randomc randomu]
2   any-old-random-text2 randome randomiest randomer randomo randomy randomx randomk randoml randomz
1   some-random-text1 [host2][randomo randomp randomr randomc randomu]
2   any-stupid-random-text2 randome randomiest randomer randomo randomy randomx randomk randoml randomz


 outfile:
user@host$ cat outfile4
**host1_ - Some Header Text We Need

1   any-random-text1 [host1][randomo randomp randomr randomc randomu]
2   any-old-random-text2 randome randomiest randomer randomo randomy randomx randomk randoml randomz
**host2_ - Some Header Text We Need

1   some-random-text1 [host2][randomo randomp randomr randomc randomu]
2   any-stupid-random-text2 randome randomiest randomer randomo randomy randomx randomk randoml randomz

【问题讨论】:

  • 如果您执行以下操作,澄清您想要的内容会很有帮助:我有如下所示的输入文件:...我想要如下所示的输出:...
  • 我试过了——我把我的例子做得尽可能小。我希望 outfile4 看起来像 outfile4 但有一个 while 循环,而不是使用手动 sed 命令。 outfile4 来自开头的 outfile 示例文件 - 我希望 while 循环生成 output4 文本,就像我的示例中的 sed 命令一样。
  • 我的输入文件是outfile 我的输出文件是outfile4。我用手动 sed/grep 命令展示了我的工作示例。我展示了它如何不适用于我的 while 循环。我希望 while 循环完全按照它的显示方式创建 outfile4
  • 好的,当我深入研究它时,我明白了你在问什么......还有一个问题。你如何判断一行是“some-random-text”还是“string2 random-text2”? “some-random-text”是一个词,“string2”行是两个词吗?
  • 你能从“string1”中找出“string2”,还是从“random-text2”中找出“random-text1”?

标签: bash loops sed while-loop grep


【解决方案1】:
$ cat /tmp/x.sh
#!/bin/sh

input="/tmp/infile.txt"
output="/tmp/outfile4.txt"
hosts="/tmp/hosts.txt"

header="blah blah blah"

for host in $(cat "${hosts}")
do
  echo "**${host}_ - ${header}"
  echo ""
  awk '/\[.*\]$/{n=0}(/\['${host}'\]$/||n){n++}n' "${input}" | sed 's/^/    /'    
done > "${outfile}"

输入文件:

$ cat /tmp/infile.txt 
 1   any-random-text1 [host1]
 2   any-old-random-text2
 1   some-random-text1 [host2]
 2   any-stupid-random-text2
$ cat /tmp/hosts.txt 
host1
host2

输出:

$ /tmp/x.sh
$ cat /tmp/outfile4.txt
**host1_ - blah blah blah

     1   any-random-text1 [host1]
     2   any-old-random-text2
**host2_ - blah blah blah

     1   some-random-text1 [host2]
     2   any-stupid-random-text2

awk 语句依赖于在 "any--random-text 中没有任何匹配的 [.]$。如果这有可能在您的 infile 中,那么更明确的模式匹配需要。

【讨论】:

  • 据我所知,这可以满足您的要求。
  • 这似乎可以解决问题,但问题是它正在寻找随机文本。随机文本在示例中无关紧要 - 我唯一需要做的就是搜索 host1和主机2
  • 它似乎适用于添加标题和空白行,但它正在从文件中删除行 - 它删除了第 2 行和第 4 行
  • 我确实修改了上面的outfile,因为它不是很清楚。我应该调用 outfile=infile 和 outfile4=outfile。无论如何 - 我会尝试使用您的示例,因为它非常接近我想要做的只是需要修改它以不从文件中删除任何行。
  • 我应该说,从它找到 host1 开始 - 在报告的下面有几百行重要数据 - 所以标题是为 host1 和下面的空行制作的header.... 然后它找到 host2 ,然后有几百行数据是针对 host2 等的,并且针对 30 台主机。
猜你喜欢
  • 1970-01-01
  • 2021-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多