sed: 2 строки/d (Что здесь не так ?)

На самом деле это единственный раздел про unix на этом форуме

Модератор: /dev/random

kotnaton
Сообщения: 226

sed: 2 строки/d

Сообщение kotnaton » 04.05.2014 13:29

Собственно, что здесь не так ?

Код: Выделить всё

sed '/#EXTINF.*$^udp:\/\/@239.64.64.253:1234$' iptv.m3u

Пробую так же и так:

Код: Выделить всё

sed 's/#EXTINF.*$^.*239.64.64.253:1234//g' iptv.m3u


собственно надо найти и удалить из m3u всегда по 2 строки:

Код: Выделить всё

#EXTINF:0 tvg-name="случайный текст TV" tvg-shift="0", случайный текст
udp://@239.64.64.253:1234
бывает же такое ???
Спасибо сказали:

Аватара пользователя
/dev/random
Администратор
Сообщения: 4706
ОС: Gentoo

Re: sed: 2 строки/d

Сообщение /dev/random » 04.05.2014 13:40

"^" и "$" предназначены для привязки начала или конца выражения к, соответственно, началу или концу обрабатываемой строки. В середине выражения они работать не будут.
Спасибо сказали:

Аватара пользователя
SLEDopit
Модератор
Сообщения: 4620
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: sed: 2 строки/d

Сообщение SLEDopit » 04.05.2014 14:13

Код: Выделить всё

sed '/^#EXTINF/{N;/@239.64.64.253:1234$/d}'
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:

kotnaton
Сообщения: 226

Re: sed: 2 строки/d

Сообщение kotnaton » 05.05.2014 21:17

SLEDopit писал(а):
04.05.2014 14:13

Код: Выделить всё

sed '/^#EXTINF/{N;/@239.64.64.253:1234$/d}'


Спасибо ! А 'N:' это что за оператор ? И будет ли верно 'N;N;N;' , допустим , для такого же действия на 4 строчки вверх ?

Если можно еще похожий вопрос, в интернете решения не нашел: как удалить (включая) весь текст между /regexp1/ и /regexp2/ содержащий строку regexp3 ? Например, <title> и </title> где есть слово "радио" ?
Нашел такой конструктор:

Код: Выделить всё

sed -n 's/.*<title>\(.*\)<\/title>.*/\1/ip'

Понятно, что /\1 это какая-то подстановка, но откуда она берется ???
бывает же такое ???
Спасибо сказали:

Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: sed: 2 строки/d

Сообщение drBatty » 05.05.2014 22:14

kotnaton писал(а):
05.05.2014 21:17
Понятно, что /\1 это какая-то подстановка, но откуда она берется ???

из круглых скобок ().
см учебник в моей подписи
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:

Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: sed: 2 строки/d

Сообщение drBatty » 05.05.2014 22:19

/dev/random писал(а):
04.05.2014 13:40
"^" и "$" предназначены для привязки начала или конца выражения к, соответственно, началу или концу обрабатываемой строки. В середине выражения они работать не будут.

будут:

$

$ echo "line1 line2 line3" | sed 'N;N;s/^/%&%/g' %%line1 line2 line3 $ echo "line1 line2 line3" | sed 'N;N;s/^/%&%/mg' %%line1 %%line2 %%line3


в первой команде не работает, а во второй -- работает (:
если надо, что-бы и во второй НЕ работало в середине, тогда так:

$

$ echo "line1 line2 line3" | sed 'N;N;s/\`/%&%/mg' %%line1 line2 line3



PS: я имел ввиду "в середине строки ^ (не)работает". В середине выражения работать -- работает, но смысла не имеет.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:

Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: sed: 2 строки/d

Сообщение drBatty » 05.05.2014 22:24

kotnaton писал(а):
05.05.2014 21:17
А 'N:' это что за оператор ?

это команда. see http://emulek.github.io/sed/ch05.html#id2528471
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:

kotnaton
Сообщения: 226

Re: sed: 2 строки/d

Сообщение kotnaton » 10.07.2018 12:31

Вернусь к теме. Обнаружил, что каталогизатор для CD, написанный для себя пару лет назад, перестал работать, оказалось что Udiskctl info -b /dev/sr0 выдаёт теперь две строки Size:

Код: Выделить всё

/org/freedesktop/UDisks2/block_devices/sr0:
  org.freedesktop.UDisks2.Block:
    Configuration:              []
    CryptoBackingDevice:        '/'
    Device:                     /dev/sr0
    DeviceNumber:               2816
    Drive:                      '/org/freedesktop/UDisks2/drives/HL_DT_ST_DVDRAM
    HintAuto:                   true
    HintIconName:               
    HintIgnore:                 false
    HintName:                   
    HintPartitionable:          false
    HintSymbolicIconName:       
    HintSystem:                 false
    Id:                         by-uuid-2018-03-10-11-41-22-00
    IdLabel:                    Debian 9.4.0 amd64 1
    IdType:                     iso9660
    IdUUID:                     2018-03-10-11-41-22-00
    IdUsage:                    filesystem
    IdVersion:                  Joliet Extension
    MDRaid:                     '/'
    MDRaidMember:               '/'
    PreferredDevice:            /dev/sr0
    ReadOnly:                   true
    Size:                       3977379840
    Symlinks:                   /dev/cdrom
                                /dev/disk/by-id/ata-HL-DT-ST_DVDRAM
                                /dev/disk/by-id/wwn-0x5001480000000000
                                /dev/disk/by-label/Debian\x209.4.0\x20amd64\x201
                                /dev/disk/by-path/pci-0000:00:1f.2-ata-2
                                /dev/disk/by-uuid/2018-03-10-11-41-22-00
    UserspaceMountOptions:      
  org.freedesktop.UDisks2.Filesystem:
    MountPoints:        
    Size:               0
Собственно как оставить Size из блока org.freedesktop.UDisks2.Block, и игнорировать всё остальное; попытка сделать так:

Код: Выделить всё

sed 's/\(Size*Symlinks\)/\1/g'
ничего не меняет, строка же

Код: Выделить всё

sed '/Size*Symlinks/p'
приводит к дублированию всех строк, а

Код: Выделить всё

sed '/Size*Symlinks/!d'
приводит возврату трёх строк, включая и паразитную Size из блока щrg.freedesktop.UDisks2.Filesystem::(
Последний раз редактировалось kotnaton 10.07.2018 12:38, всего редактировалось 1 раз.
бывает же такое ???
Спасибо сказали:

Аватара пользователя
Vascom
Сообщения: 1332
ОС: Fedora 29

Re: sed: 2 строки/d

Сообщение Vascom » 10.07.2018 12:37

Покажи свой скрипт.
Спасибо сказали:

kotnaton
Сообщения: 226

Re: sed: 2 строки/d

Сообщение kotnaton » 10.07.2018 12:42

Ну я там кое чего поломал, но... вот:

Код: Выделить всё

#!/bin/bash
set -x

pause_cd() {
eject -t
i=0
until [[ $insert_cd -ne 0 ]]
	do
		insert_cd=$( udisksctl info -b /dev/sr0 | grep Size: | awk '{ print $2 }' )
		sleep 1 
		i=$((i+1))
		echo -n $i" "
	done
echo
}

create_tree() {
	f=`df | grep sr0 | awk -F"% " '{ print $2 }'`
	vr=$( ls -lhGg --time-style="long-iso" $( dirname $( df | grep sr0 | awk -F"% " ' { print $2 }' )) | grep $( basename $( df | grep sr0 | awk -F"% " ' { print $2 }' )) | awk '{ print $4,$5 }' )
	echo -e "Новая метка тома: $nnnn" | tee tmp
	echo -e "Старая метка тома: $old" | tee -a  tmp
	echo -e "Время создания: $vr \n\n" | tee -a tmp
	cat tmp
	razmer=$( du -hd0 "$f" )
	echo "[ "$razmer | sed 's/ \//\] \//g' >> tmp	
	tree -h "$f" | sed '1d' >> tmp 
	if [[ "$arhivate" == "yes" ]]
		then 
			find "$f" -name "*.tar.*" -exec printf '\n%.0s' {1..3} >> tmp \; -exec echo "{}" >> tmp \; -exec tar tvf "{}" >> tmp \;
			find "$f" -regex '.*\.\(zip\|rar\|7z\|arj\|cab\|chm\|wv\)' -exec printf '\n%.0s' {1..3} >> tmp \; -exec 7z l {} >> tmp \; # -exec sed -i '/^7-Zip/,/^--$/d' tmp \;			
		fi
	sed -r -i '/7-Zip/,/^--$/d' tmp
	not_rewrite
	mv tmp "`echo $nnnn`.list"
	if [[ $nl == "all" ]] ; then cat "$nnnn.list" ; fi
}

not_rewrite() {
	rewr=0
	tname="$nnnn"
	while [[ -f $nnnn.list ]]
		do		
			rewr=$(($rewr+1))  
			tname=$tname"___"$rewr
			if [[ ! -f $tname.list ]]
				then 
					nnnn=$tname 
				else	
					tname=$nnnn
			fi
		done
}

rename_list() {
	echo "Имя списка: $nnnn.list"
	if [[ -z "$na" ]] 
		then
			echo "Введите новое, или оставьте поле пустым:" ;
			read r ;
		else
			validate=`echo $nnnn | tr '[:upper:]' '[:lower:]'`
			echo "Validate name: $validate"
			if [[ $validate == *k3b* ]]
				then
				echo "Введите иное или подтвердите, нажав Enter:" ;
				read r ;
			fi
	fi
	if [ "$r" ]
		then 
			nnnn="$r"
			not_rewrite
        	        echo "Список переименован..."
			echo "Было: $old.list  Вы ввели: $r, записалось $nnnn.list"
			mv "$old.list" "$nnnn.list"
		else
			echo "Saved as $nnnn.list" 


	fi
}

eject_disc() {
	udevil umount /dev/sr0 
	eject
	echo "мы дошли до eject"
}


ME=`basename $0`
print_help() {
cat <<EOF
	Дополнительные опции

	Использование: $ME [-t|-u][-s] | [-d][-a][-l]

	Параметры:
	-t		Опция ISO9660 (может понадобиться для некоторых дисков)
	-u		Опция UDF (может понадобиться для некоторых дисков)
	-s		Монтирование в директорию /media/iso (нужен для томов с кириллицей и пробелами в названии. Права на директорию 0755 для Users ).
	-d		По-умолчанию. Без опций.
	-a		По-умолчанию yes на вопросы.
	-l		Выводить на экран содержимое готового .list
	-r		Парсить архивы. Поддержка rar,7z, и, под вопросом, zip - в будущих версиях
	-h		Справка
	-v		Версия программы

EOF
exit 0
}
boolean="0"
while getopts "tusdlahrv" "opt" ;
	do
		case "$opt" in
			t)	nt="-t iso9660"
				echo "Опция: -t iso9660"
				pause_cd
				boolean="1"				;;
			u)	nt="-t udf"
				echo "Опция: -t udf"
				pause_cd
				boolean="1"
				;;
			s)	nm="/media/iso" 
				echo "Монтируем в точку $nm"
				pause_cd 
				boolean="1"				;;
			h)	print_help
				;;
			d)	echo "По умолчанию. Без опций" 
				pause_cd
				boolean="1"
				;;
			a)	echo "Вопросов не будет..."
				na="all"
				boolean="1"
				;;
			l)	echo "По завершении увидите готовый список"
				nl="all"
				boolean="1"
				;;
			r)	echo "Будем парсить архивы: tar,rar,7z,chm,arj,zip"
				arhivate="yes"
				boolean="1"				;;
			v)	cat <<-EOF
				********* Каталогизатор v2.01.3 *********
				************** for udisks2 **************
				EOF
				exit 0
				;;
			*)	print_help
				;;
			esac
		done
if [[ $boolean == "0" ]] ; then print_help ; fi
if [[ ! $( mount | grep sr0 ) ]]
	then 
		echo "Монтируем... $nt $nm" ;
		udevil mount $nt /dev/sr0 $nm ;
	fi

nnnn="`udisksctl info -b /dev/sr0 | grep IdLabel: | awk -F "IdLabel:" '{ print $2 }' | sed 's/   .//g' | sed 's/^-//g'`"

if [[ -z "$nnnn" ]]
	then
		nnnn=`echo $( isoinfo -i /dev/sr0 -d | sed '/Volume id: /!d' | sed 's/Volume id: //g')`
	echo "isoinfo -i"
	fi
old=$nnnn
create_tree 
if [[ "$na" == "all" ]] 
	then 
		eject_disc ;
		rename_list ;
	else
		echo "Ваш диск был вставлен, вынуть ?"
		read "r"
		case "$r" in
			y|Y|д|Д|""|н|Н)	echo "Вынимаем..." ;
			eject_disc ;
			rename_list ;
			;;
			n|N|т|Т)	echo "Выходим..." ;
			rename_list ;
			;;
		esac
	fi
exit 0
Собственно, проблема в самом начале:

Код: Выделить всё

insert_cd=$( udisksctl info -b /dev/sr0 | grep Size: | awk '{ print $2 }' 
Теперь возрващаются две строки Size, что приводит к ошибке "0: синтаксическая ошибка в выражении (неверный маркер «0»)"
Последний раз редактировалось kotnaton 10.07.2018 12:47, всего редактировалось 1 раз.
бывает же такое ???
Спасибо сказали:

Аватара пользователя
Vascom
Сообщения: 1332
ОС: Fedora 29

Re: sed: 2 строки/d

Сообщение Vascom » 10.07.2018 12:46

Вместо

Код: Выделить всё

insert_cd=$( udisksctl info -b /dev/sr0 | grep Size: | awk '{ print $2 }' )
сделай

Код: Выделить всё

insert_cd=$( udisksctl info -b /dev/sr0 | grep -m 1 Size: | awk '{ print $2 }' )
Спасибо сказали:

kotnaton
Сообщения: 226

Re: sed: 2 строки/d

Сообщение kotnaton » 10.07.2018 12:56

Собственно, это первое чего хотелось сделать, но больше хочется выхлоп привязать именно к блоку /org/freedesktop/UDisks2/block_devices/sr0, собственно, вопрос именно про то как это парсить :)
бывает же такое ???
Спасибо сказали:

Аватара пользователя
Vascom
Сообщения: 1332
ОС: Fedora 29

Re: sed: 2 строки/d

Сообщение Vascom » 10.07.2018 12:58

А чем не устраивает? Всегда же будет работать.
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 14812
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: sed: 2 строки/d

Сообщение Bizdelnick » 10.07.2018 13:15

kotnaton писал(а):
10.07.2018 12:31
как оставить Size из блока org.freedesktop.UDisks2.Block, и игнорировать всё остальное
Плохая идея делать это с помощью sed.

Код: Выделить всё

#!/bin/sed -nrf

/^  org\.freedesktop\.UDisks2\.Block:$/ {
:loop
  n
  /^  [^[:space:]]/q
  /^    Size:[[:space:]]*[[:digit:]]*/p
  b loop
}
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
команда
новичок
нюанс
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

kotnaton
Сообщения: 226

Re: sed: 2 строки/d

Сообщение kotnaton » 25.07.2018 07:20

Vascom писал:
10.07.2018 12:58
А чем не устраивает?
В конце-концов, по вашему и сделал :)
Bizdelnick писал:
10.07.2018 13:15
Плохая идея делать это с помощью sed.

Код: Выделить всё

sed -nrf

/^  org\.freedesktop\.UDisks2\.Block:$/ {
:loop
  n
  /^  [^[:space:]]/q
  /^    Size:[[:space:]]*[[:digit:]]*/p
  b loop
}
Спасибо за интересный пример :) А, собственно, без sed как ещё можно ?
бывает же такое ???
Спасибо сказали:

Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 7879
Статус: Маньяк
ОС: Android, GNU/Linux, Windows

Re: sed: 2 строки/d

Сообщение serzh-z » 25.07.2018 16:06

kotnaton писал(а):
25.07.2018 07:20
без sed
Я бы это сделал через D-Bus напрямую в обход клиента UDisks2.

Если система с systemd, то можно использовать клиент sd-bus:

Shell

busctl get-property org.freedesktop.UDisks2 /org/freedesktop/UDisks2/block_devices/sr0 org.freedesktop.UDisks2.Block Size | awk '{ print $2 }'
Либо с помощью Python и pydbus:

Shell

python -c "import pydbus; print pydbus.SystemBus().get('.UDisks2', 'block_devices/sr0')['org.freedesktop.UDisks2.Block'].Size"
Scio me nihil scire.
Спасибо сказали:

kotnaton
Сообщения: 226

Re: sed: 2 строки/d

Сообщение kotnaton » 05.10.2018 16:44

Не стану открывать новую, продолжу старую:

Нужно в выводе команды ls итоговый размер директории переместить в строку к пути, и вместо:

Код: Выделить всё

./folder8/subfolder1:
итого 0
Получить что-то типа:

Код: Выделить всё

итого 0: ./folder8/subfolder1:
Само собой напрашивающееся ничего возвращает... :)

Код: Выделить всё

sed -ne 'N;x;s/итого \([0-9KMGT]\)/\{N;p}\1/g'
бывает же такое ???
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 14812
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: sed: 2 строки/d

Сообщение Bizdelnick » 05.10.2018 16:54

sed -r '/:$/{N;s/(.*)\n(.*)/\2: \1/}'
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
команда
новичок
нюанс
приемлемо
проблема
пробовать
трафик
Спасибо сказали: