sed: удалить все строки до совпадающей, включая эту

Es una extensión de Apple para almacenar metadatos de archivos adicionales.

Configure la variable de entorno COPYFILE_DISABLEpara desactivar este comportamiento.

Ejemplo:

$ COPYFILE_DISABLE=1 tar -czvf tests.tar.gz test1.csv test2.csv test3.csv

(Fuente.)

2
02.08.2019, 10:56
6 ответов

Похоже на ваше "чистое решение":

sed -e '1,/HI_THERE/d' input_file

Первая строка в файле — это строка 1 -специального ^адреса нет, потому что вы всегда это знаете, в то время как $нужен в конце, потому что вы не (обязательно )знаете какая это линия.

Это происходит, если совпадающая строка является первой строкой файла. С GNU sed вы можете использовать 0вместо 1, чтобы справиться с этим. Для POSIX sed и для переносимости (, которые кажутся разными в данном случае )это более сложно (см. комментарии ниже и этот последующий -вопрос).

5
27.01.2020, 21:58

Если вы хотите придерживаться Posix sed, вы можете использовать это:

sed -ne '
  /HI_THERE/!d
  :loop
    n
    p
  bloop
' inp.file

Или в сжатой форме:

sed -n '/HI_THERE/!d;:a;n;p;ba' inp.file
0
27.01.2020, 21:58
$ perl -ne 'print if 1 <(/HI_THERE/...eof)' input_file

Где мы используем оператор диапазона ..., чтобы сформировать правильный диапазон и дополнительно ограничить его, чтобы отклонить первый элемент в выбранном диапазоне.

0
27.01.2020, 21:58

сед

В sed нет простого способа сделать то, что вы просите.
Самое простое переносимое POSIXly-решение для sed — что-то вроде:

sed -ne '/HI/{:1' -e 'n;p;b1' -e '}'

Другими простыми решениями являются:

sed '0,/HI/d'     ./file             # GNU sed
awk 'f; /HI/{f=1}'./file

изд

Ближайшее решение POSIXly non -sed — это ed. Просто удалите диапазон от первой строки файла до регулярного выражения /HI/, даже если HIнаходится в той же первой строке.

printf '%s\n' 1,/HI/d,p Q | ed -s file

Или

ed -Gs imfile2 <<-\edscript
1,/HI/d
,p
Q
edscript

Что означает:

  • печать без дополнительной информации (количество прочитанных строк )с опцией-s
  • удалить (удалить )все строки от первой строки fileдо регулярного выражения/HI/(1,/HI/d).
  • , затем распечатайте весь файл (,p).
  • и выйти, даже если файл был изменен(Q).

Если вы хотите изменить файл, замените ,p Qпростоw(и запишите в файл ).

Почему sedне работает на 1,/HI/d, а edработает?

Потому что sedожидает совпадения регулярного выражения на следующей строке.

В edлибо 3,33,/3//3/,3/3/,/3/, либо3,33,/3//3/,3/3/,/3/будет напечатано только одно 3:

$ printf '%s\n' 3,3p   3,/3/p   /3/3p   /3/,/3/p   Q | ed -s <(seq 5)
3
3
3
3

Пока этим занимается sed:

$ sed -ne 3,3p  <(seq 5)
3

$ sed -ne 3,/3/p  <(seq 5)
3
4
5

$ sed -ne /3/,3p  <(seq 5)
3

$ sed -ne /3/,/3/p <(seq 5)
3
4
5

Ожидается, что регулярное выражение в конце диапазона будет соответствовать строке , следующей за строкой, соответствующей началу диапазона (слева от,). Нет 3следующей за строкой с номером 3, поэтому sed печатает все следующие строки(4и5).

Вот почему GNU sed решает проблему с помощью 0,/HI/.

Почему :1;n;p;b1?

Способ печати всех строк (, кроме первой )диапазона, заключается в использовании цикла, который сначала запрашивает следующую строку, а , а затем печатает ее:

$     sed -n '5{:1;n;p;b1}' <(seq 8)    # GNU syntax
6
7
8

Итак, просто сопоставьте нужное регулярное выражение /HI/и войдите в такой цикл.

sed -n '/HI/{:1;n;p;b1}' file        # GNU syntax

Который необходимо расширить до более сложного сценария, потому что некоторые старые sed не позволяют завершить labelsс помощью ;.

sed -n -e '/HI/{:1' -e 'n;p;b1' -e '}' file        # portable syntax
0
27.01.2020, 21:58

grep -nw HI_THERE file.txt |awk -F":" '{print $1}' | xargs -I % sed '1,%d' file.txt

Объяснение :Я grep использую точное слово w, получаю номер строкиn
Затем я вытаскиваю номер строки с помощью awk, разделитель:
Далее я передаю это с помощью xargs и удаляю до тех пор.

0
27.01.2020, 21:58

sed предназначен для выполнения s/old/new для отдельных строк, вот и все. Для чего-либо еще вы должны использовать awk, например. с любым awk в любой оболочке на каждом компьютере UNIX и обработкой «HI _THERE» в любой строке:

$ awk 'f; /HI_THERE/{f=1}' file
lemon
coconut
orange

Если вы хотите использовать GNU sed для -i, используйте вместо этого GNU awk для -i inplace. См.https://stackoverflow.com/a/17914105/1745001для других скриптов для выбора разделов файлов.

0
27.01.2020, 21:58

Теги

Похожие вопросы