Как я обрезаю ведущий и запаздывающий пробел от каждой строки некоторого вывода?

Если я вспоминаю правильно, что Фырканье может выборочно контролировать трафик на основе определяемых пользователем правил. Однако Фырканье не создаст журналы для запросов DNS, когда Ваш компьютер, т.е. его сопоставитель, сможет ответить на вопрос от своего кэша.

172
26.08.2019, 13:24
6 ответов
awk '{$1=$1;print}'

или короче:

awk '{$1=$1};1'

обрезает ведущее и конечное пространство или символы табуляции 1 , а также сжимает последовательности табуляций и пробелов в один пробел.

Это работает, потому что когда вы присваиваете что-то одному из полей , awk перестраивает всю запись (как напечатано в print), объединяя все поля ($1, ..., $NF) с OFS (пространство по умолчанию).

1(и, возможно, другие пустые символы в зависимости от локали и реализации awk)

225
27.01.2020, 19:28

Команда может быть сжата как поэтому при использовании GNU sed:

$ sed 's/^[ \t]*//;s/[ \t]*$//' < file

Пример

Вот вышеупомянутая команда в действии.

$ echo -e " \t   blahblah  \t  " | sed 's/^[ \t]*//;s/[ \t]*$//'
blahblah

Можно использовать hexdump подтвердить что sed команда разделяет требуемые символы правильно.

$ echo -e " \t   blahblah  \t  " | sed 's/^[ \t]*//;s/[ \t]*$//' | hexdump -C
00000000  62 6c 61 68 62 6c 61 68  0a                       |blahblah.|
00000009

Классы символов

Можно также использовать имена класса символов вместо того, чтобы буквально перечислить наборы как это, [ \t]:

$ sed 's/^[[:blank:]]*//;s/[[:blank:]]*$//' < file

Пример

$ echo -e " \t   blahblah  \t  " | sed 's/^[[:blank:]]*//;s/[[:blank:]]*$//'

Большинство инструментов GNU, которые используют регулярные выражения (regex), поддерживает эти классы.

 [[:alnum:]]  - [A-Za-z0-9]     Alphanumeric characters
 [[:alpha:]]  - [A-Za-z]        Alphabetic characters
 [[:blank:]]  - [ \x09]         Space or tab characters only
 [[:cntrl:]]  - [\x00-\x19\x7F] Control characters
 [[:digit:]]  - [0-9]           Numeric characters
 [[:graph:]]  - [!-~]           Printable and visible characters
 [[:lower:]]  - [a-z]           Lower-case alphabetic characters
 [[:print:]]  - [ -~]           Printable (non-Control) characters
 [[:punct:]]  - [!-/:-@[-`{-~]  Punctuation characters
 [[:space:]]  - [ \t\v\f]       All whitespace chars
 [[:upper:]]  - [A-Z]           Upper-case alphabetic characters
 [[:xdigit:]] - [0-9a-fA-F]     Hexadecimal digit characters

Используя их вместо литеральных наборов всегда походит на трату пространства, но если Вы будете обеспокоены своим кодом, являющимся портативным, или имеющий необходимость иметь дело с альтернативными наборами символов (думайте международные), то затем Вы, вероятно, захотите использовать имена классов вместо этого.

Ссылки

50
27.01.2020, 19:28
  • 1
    Отметьте это [[:space:]] не эквивалентно [ \t] в общем случае (unicode, и т.д.). [[:space:]] вероятно, будет намного медленнее (поскольку существует намного больше типов пробелов в unicode, чем просто ' ' и '\t'). То же самое для всего другие. –  Olivier Dulac 21.11.2013, 14:44
  • 2
    sed 's/^[ \t]*//' не является портативным. Atually POSIX даже требует что удалить последовательность пространства, обратной косой черты или t символы, и это что GNU sed также делает когда POSIXLY_CORRECT находится в среде. –  Stéphane Chazelas 11.08.2016, 17:56

Как предложил Stéphane Chazelas в принятом ответе, Вы можете теперь
создайте сценарий /usr/local/bin/trim:

#!/bin/bash
awk '{$1=$1};1'

и дайте тому исполняемому файлу файла права:

chmod +x /usr/local/bin/trim

Теперь можно передать каждый вывод trim например:

cat file | trim

(для комментариев ниже: я использовал это прежде: while read i; do echo "$i"; done
который также хорошо работает, но менее производителен),

24
27.01.2020, 19:28
  • 1
    , если Ваш файл огромен и/или содержит обратные косые черты. –  don_crissti 31.12.2014, 03:31
  • 2
    @don_crissti: Вы могли прокомментировать немного больше?, какое решение лучше соответствовало бы огромным файлам, и как я мог изменить свое решение, если бы файл содержал обратные косые черты? –  rubo77 31.12.2014, 12:42
  • 3
    Необходимо будет использовать while read -r line сохранить обратные косые черты и даже затем.... Относительно огромных файлов / скорость, действительно, Вы выбрали худшее решение. Я не думаю, что там существует что-либо худшее. См. ответы на том, Почему использование является циклом оболочки к тексту процесса плохая практика? включая мой комментарий к последнему ответу, где я добавил ссылку к сравнительному тесту скорости. sed ответы здесь являются превосходным IMO и намного лучше, чем read. –  don_crissti 31.12.2014, 14:24
  • 4
    @don_crissti... и/или имею строки, запускающиеся с - и сопровождаемый комбинациями 1 или более e, E или n символов, и/или содержит символы NUL. Кроме того, ненагруженная линия после последней новой строки будет пропущена. –  Stéphane Chazelas 27.05.2015, 17:52
  • 5
    Можно также добавить псевдоним в/etc/profile (или ~/.bashrc или ~/.zshrc и т.д....) обрезка псевдонима = "awk '{\\1$ = \1$}; 1'" –  Jeff Clayton 20.11.2015, 18:26

sed является большим инструментом для этого:

                        # substitute ("s/")
sed 's/^[[:blank:]]*//; # parts of lines that start ("^")  with a space/tab 
     s/[[:blank:]]*$//' # or end ("$") with a space/tab
                        # with nothing (/)

Можно использовать его для случая или передать по каналу в тексте, например.

<file sed -e 's/^[[...

или путем действия на него 'встраивают' если Ваш sed GNU один:

sed -i 's/...' file

но изменяя источник этот путь "опасен", поскольку это может быть неисправимо, когда он не работает правильно (или даже когда он делает!), так скопируйте сначала (или использование -i.bak который также обладает преимуществом, чтобы быть портативным к некоторому BSD seds)!

6
27.01.2020, 19:28
sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'

Если Вы читаете строку в переменную оболочки, read уже делает это, если не проинструктировано иначе.

18
27.01.2020, 19:28
  • 1
    +1 для read. Таким образом, если Вы передаете по каналу к, в то время как считано, это работает: cat file | while read i; do echo $i; done –  rubo77 21.11.2013, 05:36
  • 2
    @rubo за исключением того, что в Вашем примере неупомянутая переменная также повторно обрабатывается оболочкой. Использовать echo "$i" видеть истинный эффект read –  roaima 09.09.2015, 22:19

xargs без аргументов.

Пример:

trimmed_string=$(echo "no_trimmed_string" | xargs) 
23
27.01.2020, 19:28

Теги

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