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


Следите за новостями русскоязычного сообщества Ubuntu в Twitter-ленте @ubuntu_ru_loco

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

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

  • Старожил
  • *
  • Сообщений: 2628
    • Просмотр профиля
Можно и башем:
Код: Bash
  1. while read line
  2. do
  3.         ar=($line)
  4.         echo "Первое поле: ${ar[0]}"
  5.         echo "Второе поле: ${ar[1]}"
  6.         echo "Третье поле: ${ar[2]}"
  7. 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

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

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

Пользователь добавил сообщение 30 Апрель 2017, 17:21:13:
Еще на bash:
Код: Bash
  1. while read line
  2. do
  3.         ar=($line)
  4.         first=${ar[0]}
  5.         last_n=$((${#ar[*]}-1))
  6.         last="${ar[$last_n]}"
  7.         unset ar[0] ar[$last_n]
  8.  
  9.         echo "Первое поле: $first"
  10.         echo "Поля между: ${ar[*]}"
  11.         echo "Последнее поле: $last"
  12.  
  13. done
  14.  

Код: Bash
  1. while read line
  2. do
  3.         first=${line%% *}
  4.         last=${line##* }
  5.         between=${line#$first}
  6.         between=${between%$last}
  7.  
  8.         echo "Первое поле: $first"
  9.         echo "Поля между: $between"
  10.         echo "Последнее поле: $last"
  11.  
  12. done

Awk скрипт:
Код: awk
  1. #!/usr/bin/awk -f
  2. {
  3. first=$1
  4. $1=""
  5. last=$NF
  6. $NF=""
  7. printf first "\n" $0 "\n" last "\n"
  8. }

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

Оффлайн Azure

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

Оффлайн ReNzRv

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

 

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