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

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

172
26.08.2019, 13:24
15 ответов
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

Чтобы удалить все ведущие и последующие пробелы из заданной строки благодаря инструменту 'piped', я могу выделить 3 различных способа, которые не являются полностью эквивалентными. Эти различия касаются пробелов между словами входной строки. В зависимости от ожидаемого поведения, вы сделаете свой выбор.

Примеры

Чтобы объяснить различия, рассмотрим эту фиктивную строку ввода:

"   \t  A   \tB\tC   \t  "

tr

$ echo -e "   \t  A   \tB\tC   \t  " | tr -d "[:blank:]"
ABC

tr - это действительно простая команда. В данном случае она удаляет любой пробел или символ табуляции.

awk

$ echo -e "   \t  A   \tB\tC   \t  " | awk '{$1=$1};1'
A B C

awk удаляет ведущие и концевые пробелы и сжимает до одного пробела все пробелы между словами.

sed

$ echo -e "   \t  A   \tB\tC   \t  " | sed 's/^[ \t]*//;s/[ \t]*$//'
A       B   C

В этом случае sed удаляет ведущие и концевые пробелы, не трогая пробелы между словами.

Замечание:

В случае одного слова в строке, tr выполняет эту работу.

11
27.01.2020, 19:28

Если вы храните строки как переменные, вы можете использовать bash для выполнения этой работы:

удалить начальные пробелы из строки:

shopt -s extglob
echo ${text##+([[:space:]])}

удалить конечные пробелы из строки:

shopt -s extglob
echo ${text%%+([[:space:]])}

удалить все пробелы из строки:

echo ${text//[[:space:]]}
26
27.01.2020, 19:28

Если строка, которую вы пытаетесь обрезать, короткая и непрерывная/непрерывная, ее можно просто передать в качестве параметра любой функции bash:

    trim(){
        echo $@
    }

    a="     some random string   "

    echo ">>`trim $a`<<"
Output
>>some random string<<
3
27.01.2020, 19:28

команда перевода будет работать

cat file | tr -d [:blank:]
0
27.01.2020, 19:28

Я написал эту функцию оболочки, используя awk

awkcliptor(){
    awk -e 'BEGIN{ RS="^$" } {gsub(/^[\n\t ]*|[\n\t ]*$/,"");print ;exit}' "$1" ; } 

BEGIN{ RS="^$" }:
в начале перед началом парсинга установить запись
разделитель на none, т.е. обрабатывать весь ввод как
одна запись

gsub(this,that):
замените это регулярное выражение этой строкой

/^[\n\t ]*|[\n\t ]*$/:
этой строки поймать любой пробел перед новой строкой и класс табуляции
или опубликуйте пробел новой строки и класс табуляции и замените их на
пустая строка

print;exit:затем распечатайте и выйдите

"$1":
и передайте первый аргумент функции как
процесс с помощью awk

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

образец использования:

echo '
 ggggg    

      ' > a_file
awkcliptor a_file

выход:

ggggg

или

echo -e "\n ggggg    \n\n      "|awkcliptor 

выход:

ggggg
1
31.01.2020, 06:35

Ответ, который можно понять с первого взгляда:

#!/usr/bin/env python3
import sys
for line in sys.stdin: print(line.strip()) 

Бонус :заменитеstr.strip([chars])произвольными символами, чтобы обрезать или использовать .lstrip()или .rstrip()по мере необходимости.

Как и ответ rubo77 , сохраните как скрипт /usr/local/bin/trimи предоставьте разрешения с помощью chmod +x.

4
24.02.2020, 18:49
trimpy () {
    python3 -c 'import sys
for line in sys.stdin: print(line.strip())'
}
trimsed () {
gsed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
}
trimzsh () {
   local out="$(</dev/stdin)"
   [[ "$out" =~ '^\s*(.*\S)\s*$' ]] && out="$match[1]"  || out=''
   print -nr -- "$out"
}
# example usage
echo " hi " | trimpy

Бонус :замените str.strip([chars])произвольными символами, чтобы обрезать или использовать .lstrip()или .rstrip()по мере необходимости.

2
09.04.2020, 23:12

для примера bash:

alias trim="awk '{\$1=\$1};1'"

использование:

echo -e  "    hello\t\tkitty   " | trim | hexdump  -C

результат:

00000000  68 65 6c 6c 6f 20 6b 69  74 74 79 0a              |hello kitty.|
0000000c
0
03.09.2020, 21:27

Удалить начальный пробел и табуляцию и конечный пробел и табуляцию:

alias strip='python3 -c "from sys import argv; print(argv[1].strip(\" \").strip(\"\t\"))"'

Удалить все пробелы и вкладки

alias strip='python3 -c "from sys import argv; print(argv[1].replace(\"\t\", \"\").replace(\" \", \"\")"'

Приведите аргумент, чтобы раздеться. Используйте sys.stdin ().read (), чтобы сделать конвейерным вместо argv.

0
24.09.2021, 12:58

Теги

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