Как разделить несколько пробелов к одному использованию sed?

Нет.

PDF состоит из блоков данных, некоторые из них текст, некоторые из них изображения и некоторые из них действительно волшебный необычный XYZ (например, .u3d файлы). Те блоки являются большинством сжатых времен (например, плоский, проверьте http://www.verypdf.com/pdfinfoeditor/compression.htm). Чтобы к 'grep' .pdf необходимо инвертировать сжатие, иначе извлекают текст.

Можно сделать это любой на файл с инструментами такой как pdf2text и grep результат, или Вы выполняете 'индексатор' (взгляд на xapian.org или lucene), который создает доступный для поиска индекс из Ваших файлов pdf, и затем можно использовать инструменты поисковой системы того индексатора для получения содержания PDF.

Но не, Вы не можете grep файлы PDF и надежда на надежные ответы, не извлекая текст сначала.

71
13.08.2016, 14:01
6 ответов

Использование grep избыточно, sed может сделать то же. Проблема находится в употреблении * то соответствие также 0 пробелов, необходимо использовать \+ вместо этого:

iostat | sed -n '/hdisk1/s/ \+/ /gp'

Если Ваш sed не делайте поддержек \+ метасимвол, затем сделайте

iostat | sed -n '/hdisk1/s/  */ /gp'
56
27.01.2020, 19:31
  • 1
    AIX, кажется, не поддерживает +, но удаление [], кажется, добилось цели. –  WernerCD 19.08.2011, 18:26
  • 2
    , я пытался использовать sed-n версия..., что происходит, у меня есть другой компьютер, который имеет 10 + диски, таким образом, это начинает делать 1, 10, 11, и т.д... Я пытался добавить пространство/hdisk1 / и оно дало мне "не распознанную функцию". то, что, кажется, работает,>> iostat | grep "hdisk1" | sed-e's/*//g' –  WernerCD 19.08.2011, 18:33

/[ ]*/ нуль соответствий или больше пробелов, таким образом, пустая строка между соответствиями символов.

При попытке соответствовать "одним или нескольким пробелам", использованию одному из них:

... | sed 's/  */ /g'
... | sed 's/ \{1,\}/ /g'
... | tr -s ' '
69
27.01.2020, 19:31
  • 1
    Ahh... [] делает это "дополнительным". Это объясняет это. –  WernerCD 19.08.2011, 18:28
  • 2
    @WernerCD, нет * делает это "дополнительным". [ ] просто входит в список символов только с одним символом в нем (пространство). Это - квантор * это означает "нуль или больше предыдущей вещи" –  glenn jackman 19.08.2011, 18:33
  • 3
    Ahh... так, чтобы быть более точным, изменяя его от одиночного пробела / */, к двойному интервалу - то, что сделало это затем. Я глюк. –  WernerCD 19.08.2011, 18:50
  • 4
    я пытался искать шаблон, которые ищут только двойные интервалы только и это работало прохладное –  minhas23 19.01.2015, 10:18
  • 5
    +1 для самого простого tr -s ' ' решение –  Andrejs 09.10.2016, 15:32

Измените Ваш * оператор к a +. Вы соответствуете нулю или большему количеству предыдущего символа, который соответствует каждому символу, потому что все, что не является пространством..., гм... обнуляют экземпляры пространства. Необходимо соответствовать Одному или нескольким. На самом деле было бы лучше соответствовать два или больше

Класс символов на кронштейнах является также ненужным для соответствия одному символу. Можно просто использовать:

s/  \+/ /g

... если Вы не хотите соответствовать вкладкам или другим видам пробелов также, затем класс символов является хорошей идеей.

14
27.01.2020, 19:31
  • 1
    AIX, кажется, не поддерживает +. –  WernerCD 19.08.2011, 18:26
  • 2
    @WernerCD: Затем попробуйте s/ */ /g (это с тремя пробелами, форматирование комментария сворачивает их). Звездообразный оператор сделает предыдущий символ дополнительным, поэтому если Вы для соответствия два или больше ему, необходимо соответствовать первым двум сами (два пробелов) затем, добавите третье пространство и звезду для создания третьего и после пробелов дополнительным. –  Caleb 19.08.2011, 18:42
  • 3
    @userunknown: На самом деле я не смешиваю две вещи вообще, все другие :) Замена одиночного пробела с одиночным пробелом бессмысленна, только необходимо сделать это действие с соответствиями, которые имеют по крайней мере два последовательных пробелов. Два пробела и плюс или три пробела и звезда точно, что необходимо. –  Caleb 19.08.2011, 18:46
  • 4
    @userunknown: Дело не в этом большой соглашение это - просто трата определенного времени обработки, и это отбрасывает вещи как счетчики соответствия. –  Caleb 19.08.2011, 20:07

Заметьте, что можно также сделать то, чего Вы делаете попытку, который является

iostat | grep "hdisk1 " | sed -e's/  */ /g' | cut -d" " -f 5

iostat | while read disk tma kbps tps re wr; do [ "$disk" = "hdisk1" ] && echo "$re"; done

который мог бы быть особенно полезным, если Вы позже пытаетесь получить доступ к другим полям также и/или вычислить что-то - как это:

iostat | while read disk tma kbps tps re wr; do [ "$disk" = "hdisk1" ] && echo "$(( re/1024 )) Mb"; done
5
27.01.2020, 19:31
  • 1
    Очень хороший. Первые работы версии. Полям My AIX, кажется, не нравится второй. Все три поля производят: "$ [ре/1024] Мбит". Контрольный инструмент, который я использую, имеет преобразования для отчетов, таким образом, это не "необходимая" вещь для меня, но мне нравится он. –  WernerCD 19.08.2011, 19:59
  • 2
    @enzotib спасибо за исправление while. –  rozcietrzewiacz 19.08.2011, 22:42
  • 3
    @WernerCD, это $[ .. ] вероятно, доступно в последних версиях удара (возможно, zsh также). Я обновил ответ на более портативное $(( .. )) вместо этого. –  rozcietrzewiacz 19.08.2011, 22:47
  • 4
    Это добилось цели. Я должен буду искать это. Притягательный. –  WernerCD 20.08.2011, 01:14

Вы всегда можете сопоставить последнее возникновение в последовательности чего-либо вроде:

s/\(sequence\)*/\1/

и поэтому вы находитесь на правом пути, а вместо того, чтобы заменить последовательность с пространством - замените его последним вхождением - одному пространством Отказ Таким образом, если последовательность пространств сочкована , то последовательность уменьшается до одного пространства, но если нулевая строка соответствует, то нулевая строка заменена самами - и нет вреда, нет фола. Таким образом, например:

sed 's/\( \)*/\1/g' <<\IN                                    
# iostat
System configuration: lcpu=4 drives=8 paths=2 vdisks=0

tty:      tin         tout    avg-cpu: % user % sys % idle % iowait
          0.2         31.8                9.7   4.9   82.9      2.5

Disks:        % tm_act     Kbps      tps    Kb_read   Kb_wrtn
hdisk9           0.2      54.2       1.1   1073456960  436765896
hdisk7           0.2      54.1       1.1   1070600212  435678280
hdisk8           0.0       0.0       0.0          0         0
hdisk6           0.0       0.0       0.0          0         0
hdisk1           0.1       6.3       0.5   63344916  112429672
hdisk0           0.1       5.0       0.2   40967838  98574444
cd0              0.0       0.0       0.0          0         0
hdiskpower1      0.2     108.3       2.3   2144057172  872444176

# iostat | grep hdisk1
hdisk1           0.1       6.3       0.5   63345700  112431123

IN

вывод

# iostat
System configuration: lcpu=4 drives=8 paths=2 vdisks=0

tty: tin tout avg-cpu: % user % sys % idle % iowait
 0.2 31.8 9.7 4.9 82.9 2.5

Disks: % tm_act Kbps tps Kb_read Kb_wrtn
hdisk9 0.2 54.2 1.1 1073456960 436765896
hdisk7 0.2 54.1 1.1 1070600212 435678280
hdisk8 0.0 0.0 0.0 0 0
hdisk6 0.0 0.0 0.0 0 0
hdisk1 0.1 6.3 0.5 63344916 112429672
hdisk0 0.1 5.0 0.2 40967838 98574444
cd0 0.0 0.0 0.0 0 0
hdiskpower1 0.2 108.3 2.3 2144057172 872444176

# iostat | grep hdisk1
hdisk1 0.1 6.3 0.5 63345700 112431123

Все, что сказал, вероятно, намного лучше, чтобы полностью не повторно регулировать в этой ситуации и делать:

tr -s \  <infile
8
27.01.2020, 19:31

Вы можете использовать следующий сценарий для преобразования нескольких пробелов в один пробел, TAB или любую другую строку:

$ ls | compress_spaces.sh       # converts multiple spaces to one
$ ls | compress_spaces.sh TAB   # converts multiple spaces to a single tab character
$ ls | compress_spaces.sh TEST  # converts multiple spaces to the phrase TEST
$ compress_spaces.sh help       # show the help for this command

compress_spaces.sh

function show_help()
{
  IT=$(CAT <<EOF

  usage: {REPLACE_WITH}

  NOTE: If you pass in TAB, then multiple spaces are replaced with a TAB character

  no args -> multiple spaces replaced with a single space
  TAB     -> multiple spaces replaced with a single tab character
  TEST    -> multiple spaces replaced with the phrase "TEST"

  )
  echo "$IT"
  exit
}

if [ "$1" == "help" ]
then
  show_help
fi

# Show help if we're not getting data from stdin
if [ -t 0 ]; then
  show_help
fi

REPLACE_WITH=${1:-' '}

if [ "$REPLACE_WITH" == "tab" ]
then
  REPLACE_WITH=$'\t'
fi
if [ "$REPLACE_WITH" == "TAB" ]
then
  REPLACE_WITH=$'\t'
fi

sed "s/ \{1,\}/$REPLACE_WITH/gp"
0
27.01.2020, 19:31

Теги

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