Как использовать цикл while для непрерывного чтения текста из текстового файла и вывода текстовых параметров в команду

70
7

Мы пытаемся сделать отчет, который читает файл hosts.txt и infile. Он должен сделать заголовок, когда он найдет первый host1 над линией, содержащей текст host1 а затем поместит новую строку под только что созданной строкой заголовка, оставив все остальное без изменений и продолжая делать это для hosts1-30.

В настоящее время мы делаем это с помощью отдельных команд grep и sed в функциях. Мы добавляем текст заголовка над первым совпадением, затем добавляем одну пустую строку под этим заголовком. В этом примере мы показываем только 2 хоста host1, host2.

Мы ищем способ сделать это с циклом while вместо одиночных команд sed/grep. Хосты появляются последовательно, поскольку они находятся в infile поэтому их можно прочитать последовательно из hosts.txt в цикле while.

Вот пример выполнения команды вручную с командами sed и grep. У нас есть один входной файл infile. host1 grep/sed соответствуют host1 и host1 и host2 заголовок выше и пустую строку ниже.

infile file: весь текст является буквальным - случайный текст полностью случайный. Никогда не существует [], кроме строки, где найден 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

Теперь мы добавляем заголовок с нашим ручным sed и grep current методом работы:

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 чтобы найти host1 и host2 которую команда grep использовала выше. Содержание 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 файл output4: с помощью наших команд для команды sed и grep для нас:

 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

спросил(а) 2017-08-14T03:08:00+03:00 3 года, 1 месяц назад
1
Решение
90

$ 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 полагается на то, что не существует никакого соответствия [.] $ В "любом случайном тексте". Если возможно, что это будет в вашем infile, тогда потребуется более явное сопоставление шаблонов.

ответил(а) 2017-08-14T04:01:00+03:00 3 года, 1 месяц назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема