как мне обрезать ведущие и конечные пробелы из каждой строки некоторого вывода?

Я хотел бы удалить все начальные и конечные пробелы и вкладки из каждой строки вывода.

Есть ли простой инструмент, например, trim я мог бы вывести свой вывод?

пример файла:

 test space at back test space at front TAB at end TAB at front some empty lines with differing TABS and spaces: test space at both ends 

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

или короче:

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

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

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

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

Команда может быть сжата так, если вы используете 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:]] - [az] Lower-case alphabetic characters [[:print:]] - [ -~] Printable (non-Control) characters [[:punct:]] - [!-/:-@[-`{-~] Punctuation characters [[:space:]] - [ \t\v\f] All whitespace chars [[:upper:]] - [AZ] Upper-case alphabetic characters [[:xdigit:]] - [0-9a-fA-F] Hexadecimal digit characters 

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

Рекомендации

  • Раздел 3 часто задаваемых вопросов

Как было предложено Стефаном Чазеласом в принятом ответе, вы можете теперь
создайте скрипт /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
который также отлично работает, но менее эффективен)

 sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' 

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

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

Пример:

 trimmed_string=$(echo "no_trimmed_string" | xargs) 

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/^[[... 

или действуя на него «inline», если ваш sed является GNU:

 sed -i 's/...' file 

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

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

Примеры

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

 " \t A \tB\tC \t " 

тр

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

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

AWK

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

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

СЕПГ

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

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

Примечание:

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

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

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

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

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

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

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

 echo ${text//[[:space:]]}