Форум русскоязычного сообщества Ubuntu


Получить помощь и пообщаться с другими пользователями Ubuntu можно
на irc канале #ubuntu-ru в сети Freenode
и в Jabber конференции ubuntu@conference.jabber.ru

Автор Тема: Вывод строки, кроме первого и последнего "поля"  (Прочитано 1497 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн BAKT

  • Автор темы
  • Участник
  • *
  • Сообщений: 112
    • Просмотр профиля
Есть некий многострочный список в виде простого текста. Список, фактически, состоит из 3х частей. Количество символов во всех частях может варьироваться. Нужно отдельно вывести все три части. С выводом только первого и последнего поля я разобрался, но вот я туплю как вывести "среднюю" часть?! Может подсказать кто? А то у меня получается только 1+2, либо 2+3 :(

while IFS= read -r line; do
    echo "Первое поле:             ${line%% *}"
    echo "Основное поле:             ?????
    echo "Последнее поле:      ${line##* }"


done < ~/list.txt

list.txt
0001 стол деревянный квадратный 00001
02501 стул железный 0005555

Нужно чтобы получилось что-нибудь типа этого:

Первое поле: 0001
Основное поле: стол деревянный квадратный
Последнее поле: 00001

и т.д.

Это реально башем или нужно подключать что-нибудь типа awk?

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2648
    • Просмотр профиля
Можно и башем:
Код: (bash) [Выделить]
while read line
do
ar=($line)
echo "Первое поле: ${ar[0]}"
echo "Второе поле: ${ar[1]}"
echo "Третье поле: ${ar[2]}"
done < ~/list.txt

Оффлайн BAKT

  • Автор темы
  • Участник
  • *
  • Сообщений: 112
    • Просмотр профиля
По вашему варианту я получу:
Первое поле: 0001
Второе поле: стол
Третье поле: деревянный

а не

Первое поле: 0001
Основное поле: стол деревянный квадратный
Последнее поле: 00001

разве нет?


ТС, как видно по состоянию на 30/01/2020 потерял интерес к созданной им теме (пометка Решено в теме отсутствует, тема оставлена не закрытой, сообщений в теме давно не было). Тема стародавняя (последнее сообщение в топике: 01/05/2017; последнее сообщение от ТС в топике: 30/04/2017). Модератором раздела принято решение закрыть тему.
--zg_nico
« Последнее редактирование: 30 Января 2020, 18:55:44 от zg_nico »

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2648
    • Просмотр профиля
Да, но мог бы и сам догадатся:
Код: (bash) [Выделить]
while read line
do
ar=($line)
echo "Первое поле: ${ar[0]}"
echo -n "Поля между: " ; for ((i=1 ; i < ${#ar[*]}-1 ; i++)) ; do printf "${ar[$i]} " ; done ; echo
echo "Последнее поле: ${ar[${#ar[*]}-1]}"
done

Но лучше конечно на awk:
awk '{f=$1; $1=""; l=$NF; $NF=""; printf f "\n" $0 "\n" l "\n"}'

Пользователь добавил сообщение 30 Апреля 2017, 17:21:13:
Еще на bash:
Код: (bash) [Выделить]
while read line
do
ar=($line)
first=${ar[0]}
last_n=$((${#ar[*]}-1))
last="${ar[$last_n]}"
unset ar[0] ar[$last_n]

echo "Первое поле: $first"
echo "Поля между: ${ar[*]}"
echo "Последнее поле: $last"

done

Код: (bash) [Выделить]
while read line
do
first=${line%% *}
last=${line##* }
between=${line#$first}
between=${between%$last}

echo "Первое поле: $first"
echo "Поля между: $between"
echo "Последнее поле: $last"

done

Awk скрипт:
Код: (awk) [Выделить]
#!/usr/bin/awk -f
{
first=$1
$1=""
last=$NF
$NF=""
printf first "\n" $0 "\n" last "\n"
}

Sed:
Код: (bash) [Выделить]
sed -r 's/^(\S+)/\1\n/; s/(\S+)$/\n\1/'
« Последнее редактирование: 30 Апреля 2017, 17:57:17 от renzrv »

Оффлайн Azure

  • Почётный модератор
  • Старожил
  • *
  • Сообщений: 6017
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
renzrv, Что ж сложно у Вас так все?
Код: (bash) [Выделить]
while read -a line ; do
    printf '%s\n' "Первое поле: ${line[0]}" "Основное поле: ${line[*]:1:$[${#line[*]}-2]}" "Последнее поле: ${line[-1]}";
done
Код: (bash) [Выделить]
while read line ; do
    mid=${line#* }
    printf '%s\n' "Первое поле: ${line%% *}" "Основное поле: ${mid% *}" "Последнее поле: ${line##* }"
done
Код: (bash) [Выделить]
while read begin end ; do
    printf '%s\n' "Первое поле: $begin" "Основное поле: ${end% *}" "Последнее поле: ${end##* }"
done
Код: (bash) [Выделить]
sed '
    s/ /\nОсновное поле: /;
    s/^/Первое поле: /;
    s/\s\S*$/\nПоследнее поле:&/;
    '
Код: (awk) [Выделить]
awk '
    {
    print "Первое поле:", $1;
    printf "%s", "Основное поле:";
    for(i=2;i<NF;i++)
        printf(" %s", $i);
    print "\nПоследнее поле:", $NF
    }'
« Последнее редактирование: 30 Апреля 2017, 23:20:55 от Azure »
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2648
    • Просмотр профиля
renzrv, Что ж сложно у Вас так все?
Сильно не напрягался делать проще и короче. Выбор, упрощение и улучшение оставил для ТС.
Главное есть варианты и они работают.

 

Страница сгенерирована за 0.035 секунд. Запросов: 23.