Команда SED не работает правильно - PullRequest
2 голосов
/ 06 мая 2019

У меня есть файл test.file, в котором есть следующие строки.

abc01.hostname.com
xyzabc01.hostname.com
xyzabc02.hostname.com

У меня есть скрипт - для sed, который должен печатать вывод, как показано ниже

[abc]
abc01.hostname.com
[xyzabc]
xyzabc01.hostname.com
xyzabc02.hostname.com

Но я получаюниже вывода.

[abc]
abc01.hostname.com
[abc]
[xyzabc]
xyzabc01.hostname.com
xyzabc02.hostname.com

Не знаю, почему [abc] дублируется.Какие-либо предложения?ниже приведен скрипт, который я использую.

#!/bin/bash
for i in `test.file | cut -d. -f1 | sed 's/[0-9]//g' | uniq`
do
    {
        name=$(cat test.file | grep ^$i[0-9] | head -1)
        sed -i "/$name/i \[$i\]" test.file
    }
done

Ответы [ 4 ]

2 голосов
/ 06 мая 2019

Давайте немного исправим это.

for i in `cat test.file | cut -d. -f1 | sed 's/[0-9]//g' | uniq`

Не делайте этого.Не используйте подоболочку для предоставления списка в for, не используйте cat для подачи программ, которые могут читать файл напрямую, не используйте длинный конвейер, когда подпроцессы не нужны ...

name=$(cat test.file | grep ^$i[0-9] | head -1)

Если вы используете bash, нет необходимости запускать три (технически четыре?) Подпроцесса на каждой итерации, чтобы получить эту отредактированную строку.cf эта страница .

#!/bin/bash
last=''
while read name
do label="${name%%[.0-9]*}"
   if [[ "$label" != "$last" ]]
   then echo "[$label]" # or printf "\n$label\n" for a separator line
        last="$label"
   fi
   echo "$name"
done < test.file > file.redux

Вывод:

[abc]
abc01.hostname.com
[xyzabc]
xyzabc01.hostname.com
xyzabc02.hostname.com

Тогда, если вы удовлетворены результатами,

mv file.redux test.file

Все обработанов bash быстро и эффективно, без порождения до тех пор, пока результат не будет хорошим.

Если вы думаете, что это будет МНОГО данных, попробуйте awk с той же логикой.:)

2 голосов
/ 06 мая 2019

Я бы не использовал sed для этого.Просто сделай:

awk '$1 != last_prefix {print "[" $1 "]"} 1; {last_prefix=$1}' FS=[0-9] test.file
1 голос
/ 06 мая 2019

Вы забыли указать начало строки также в команде sed:

#!/bin/bash
for i in `cat test.file | cut -d. -f1 | sed 's/[0-9]//g' | uniq`
do
    {
        name=$(cat test.file | grep ^$i[0-9] | head -1)
        sed -i "/^$name/i \[$i\]" test.file
    }
done
0 голосов
/ 07 мая 2019

Это может работать для вас (GNU sed):

sed -E 'G;/^([[:alpha:]]+).*\n\1/{P;d};s/\n.*//;h;s/^([[:alpha:]]+).*/[\1]\n&/' file

Это решение работает путем сравнения текущего ключа с предыдущим.Предыдущий ключ хранится в области удержания и заменяется при смене ключа.При смене ключа ведущие буквенные символы преобразуются в дополнительную запись, окруженную [ и ].Если клавиша не изменена, текущая запись печатается как обычно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...