Как удалить начальные и конечные пробелы? - PullRequest
13 голосов
/ 07 февраля 2012

Я использую awk '{gsub(/^[ \t]+|[ \t]+$/,""); print;}' in.txt > out.txt для удаления начальных и конечных пробелов.

Проблема в том, что выходной файл фактически содержит конечные пробелы! Все строки имеют одинаковую длину - они дополняются пробелами.

Чего мне не хватает?

ОБНОВЛЕНИЕ 1

Проблема, вероятно, связана с тем фактом, что конечные пробелы не являются ни "нормальными" пробелами, а \ x20 символами (DC4).

ОБНОВЛЕНИЕ 2

Я использовал gsub (/'[[:cntrl:]]|[[:space:]]|\x20/,""), и это сработало. Две странные вещи:

  1. Почему \ x20 не считается управляющим символом?

  2. Использование '[[:cntrl:][:space:]\x20 НЕ работает. Почему?

Ответы [ 4 ]

25 голосов
/ 07 февраля 2012

У меня работает эта команда:

$ awk '{$1=$1}1' file.txt
4 голосов
/ 07 февраля 2012

Ваш код в порядке для меня.
У вас может быть что-то еще, кроме space и tabulation ...
hexdump -C может помочь вам проверить, что не так:

awk '{gsub(/^[ \t]+|[ \t]+$/,""); print;}' in.txt | hexdump -C | less

UPDATE:

ОК, вы определили DC4 (могут быть некоторые другие управляющие символы ...)
Затем вы можете улучшить свою команду:

awk '{gsub(/^[[:cntrl:][:space:]]+|[[:cntrl:][:space:]]+$/,""); print;}' in.txt > out.txt

См. awk справочную страницу:

[:alnum:] Alphanumeric characters.
[:alpha:] Alphabetic characters.
[:blank:] Space or tab characters.
[:cntrl:] Control characters.
[:digit:] Numeric characters.
[:graph:] Characters that are both printable and visible. (A space is printable, but not visible, while an a is both.)
[:lower:] Lower-case alphabetic characters.
[:print:] Printable characters (characters that are not control characters.)
[:punct:] Punctuation characters (characters that are not letter, digits, control characters, or space characters).
[:space:] Space characters (such as space, tab, and formfeed, to name a few).
[:upper:] Upper-case alphabetic characters.
[:xdigit:] Characters that are hexadecimal digits.

Leading / Trailing 0x20 удаление

Для меня команда в порядке, я проверил так:

$ echo -e "\x20 \tTEXT\x20 \t" | hexdump -C
00000000  20 20 09 54 45 58 54 20  20 09 0a                 |  .TEXT  ..|
0000000b
$ echo -e "\x20 \tTEXT\x20 \t" | awk '{gsub(/^[[:cntrl:][:space:]]+|[[:cntrl:][:space:]]+$/,""); print;}' | hexdump -C
00000000  54 45 58 54 0a                                    |TEXT.|
00000005

Однако, если у вас есть 0x20 в середине вашего текста
=> то не удаляется.
Но это не твой вопрос, не так ли?

1 голос
/ 07 февраля 2012

Ваши файлы, вероятно, имеют окончания строки Windows.Это означает, что они заканчиваются \r\n, поэтому сопоставление последовательности символов табуляции и пробелов в конце строки не будет работать - awk пытается сопоставить все табуляции и пробелы, которые появляются после the \r.Попробуйте запустить файл через tr -d "\r" перед отправкой в ​​awk.

0 голосов
/ 07 октября 2015

Можно использовать Perl:

perl -lpe 's/^\s*(.*\S)\s*$/$1/' in.txt > out.txt

s/foo/bar/ подставить с помощью регулярных выражений
^ начало строки
\s* ноль или более пробелов
(.*\S) любойсимволы, заканчивающиеся не пробелами.Захватите его в $ 1
\s* ноль или более пробелов
$ конец строки

...