Как удалить часть файла с помощью awk - PullRequest
1 голос
/ 28 июня 2009

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

Может ли кто-нибудь мне помочь?

Ответы [ 6 ]

8 голосов
/ 28 июня 2009

Полагаю, «awk» - это один из инструментов для работы, хотя я думаю, что «sed» проще для этой конкретной операции. Спецификация немного расплывчата. Простая версия:

  • Найти первую строку, содержащую данное слово.
  • Удалить эту строку и все последующие строки.

Для этого я бы использовал 'sed':

sed '/word/,$d' file

Более сложная версия:

  • Найти первую строку, содержащую данное слово.
  • Удалить текст в этой строке, начиная со слова.
  • Удалить все последующие строки текста.

Возможно, я бы все еще использовал 'sed':

sed -n '1,/word/{s/word.*//;p}' file

Это инвертирует логику. По умолчанию он ничего не печатает, но для строк 1 до первой строки, содержащей слово, он подставляет (что ничего не делает до строки, содержащей слово), а затем печатает.

Можно ли это сделать в 'awk'? Не совсем тривиально, потому что «awk» автоматически разбивает входные строки на слова, и потому что вы должны использовать функции для подстановок.

awk '/word/ { if (found == 0) {
                # First line with word
                sub("word.*", "")
                print $0;
                found = 1
              }
            }
            { if (found == 0) print $0; }' file

( Отредактировано : изменить «удалить» на «найдено», так как «удалить» является зарезервированным словом в «awk».)

Во всех этих примерах усеченная версия входного файла записывается в стандартный вывод. Чтобы изменить файл на месте, вам нужно либо использовать Perl или Python, либо подобный язык, либо вы записываете вывод во временный файл, который вы копируете поверх оригинала после выполнения команды. (Если вы попробуете «файл сценария», вы обработаете пустой файл.)

Существуют различные ранние оптимизации выхода, которые можно применить к сценариям sed и awk, например:

sed '/word/q' file

И, если вы предполагаете использовать GNU-версии awk или sed, существуют различные нестандартные расширения, которые могут помочь с модификацией файла на месте.

1 голос
/ 04 июля 2009
awk '/word/{exit}1' file
1 голос
/ 28 июня 2009

Я предполагаю, что ваш вклад выглядит примерно так:

Lorem ipsum dolor sit amet,
Concectetur Adipiscing Velit.
Nullam Neque Sapien, Molestie Vel Congue Non,
Feugiat Quis Tellus. Ut quis
нулла ми Меценат лигула.

и вы хотите, чтобы вывод был обрезан при слове 'vel' примерно так:

Lorem ipsum dolor sit amet,
Concectetur Adipiscing Velit.
Nullam Neque Sapien, Molestie

В этом случае ваш awk-скрипт будет:

cat lorem.txt | awk ' 
  /\<vel\>/ 
  {
     print substr($0, 0, match($0, /\<vel\>/) - 1); 
     exit; 
  } 

  { print }
'

Слово, которое вы хотите обрезать, должно заменить оба экземпляра слова vel в сценарии.

Вы также можете безопасно поместить весь скрипт в одну строку.

0 голосов
/ 30 июня 2011

Для удаления части строки с помощью sed, например:

$ echo '12345 John Smith / red black or blue it is a test' | sed -e 's/\/.*//'

$ 12345 John Smith 
0 голосов
/ 28 июня 2009

Этот awk однострочный должен сделать трюк: {sub (/ word. * /, ""); Распечатать } Для каждой строки, если строка содержит шаблон, который начинается со слова (после пробела) и идет до конца строки - замените шаблон пустой строкой - затем выведите обновленную строку.

[Пояснил, что вопрос может быть прочитан любым способом (весь текст в этой строке или весь текст в файле). Если кто-то хочет пропустить оставшуюся часть файла, он может: {skip = gsub (/ word. * /, ""); Распечатать ; if (skip) exit}]

0 голосов
/ 28 июня 2009

Я не уверен, как это сделать с помощью awk, но вы могли бы сделать это с помощью sed:

sed -i~ -e 's/the-word-to-find.*$//' the-file

Это удалит все от the-word-to-find до конца строки, в каждой строке, содержащей the-word-to-find. Если вы хотите удалить оставшуюся часть файла при первом появлении the-word-to-find, вы можете сделать:

sed -i~ -e 's/\(the-word-to-find\).*$/\1/;/the-word-to-find/,$d'
...