Подтвердить что ты не робот

Grep: совпадение всех символов до (не включая) первого пробела

У меня есть текстовый файл, который имеет следующий формат:

characters(that I want to keep) (space) characters(that I want to remove)

Итак, например:

foo garbagetext
hello moregarbage
keepthis removethis
(etc.)

Итак, я пытался использовать команду grep в Linux, чтобы сохранить только символы в каждой строке и не включать в себя первое пустое пространство. Я пробовал множество попыток, таких как:

grep '*[[:space:]]' text1.txt > text2.txt
grep '*[^\s]' text1.txt > text2.txt
grep '/^[^[[:space:]]]+/' text1.txt > text2.txt

пытается объединиться из разных примеров, но мне не повезло. Все они создают пустой файл text2.txt. Я новичок в этом. Что я делаю неправильно?

* EDIT:

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

** EDIT:

Текст мусора (который я хочу удалить) может содержать все, включая пробелы, специальные символы и т.д. Так, например:

AA rough, cindery lava [n -S]

После запуска grep -o '[^ ]*' text1.txt > text2.txt строка выше будет выглядеть следующим образом:

AA
rough,
cindery
lava
[n
-S]

в text2.txt. (Все, что я хочу сохранить, AA)


РЕШЕНИЕ (предоставлено Rohit Jain с дополнительным вводом beny23):

 grep -o '^[^ ]*' text1.txt > text2.txt
4b9b3361

Ответ 1

Вы помещаете квантификатор * в неправильное место.

Попробуйте вместо этого: -

grep '^[^\s]*' text1.txt > text2.txt

или, что еще лучше: -

grep '^\S*' text1.txt > text2.txt  

\S означает совпадение символа без пробелов. И привязка ^ используется для совпадения в начале строки.

Ответ 2

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

Поскольку вы не выполняете сложный сопоставление текстовых шаблонов, просто используя первый столбец, ограниченный пробелом, вы можете использовать некоторые из утилит, которые основаны на столбцах, например awk или cut.

Использование awk

$ awk '{print $1}' text1.txt > text2.txt

Использование cut

$ cut -f1 -d' ' text1.txt > text2.txt

Тесты на файле размером 1,1 МБ

$ time grep -o '^[^ ]*' text1.txt > text2.txt

real    0m0.064s
user    0m0.062s
sys     0m0.001s
$ time awk '{print $1}' text1.txt > text2.txt

real    0m0.021s
user    0m0.017s
sys     0m0.004s
$ time cut -f1 -d' ' text1.txt > text2.txt

real    0m0.007s
user    0m0.004s
sys     0m0.003s

awk примерно в 3 раза быстрее, чем grep, а cut примерно в 3 раза быстрее, чем это. Опять же, нет небольшой разницы для этого небольшого файла за один проход, но если вы пишете script, например, для повторного использования или часто это делаете на больших файлах, вы можете оценить дополнительную эффективность.

Ответ 3

Я часто использую egrep, чтобы помочь "раскрасить" строки журнала, поэтому я всегда ищу новый поворот в регулярном выражении. Для меня выше это работает лучше, добавив \W вот так:

$ egrep --color '^\S*\W|bag' /tmp/barf -o
foo
bag
hello
bag
keepthis
(etc.)

Проблема в том, что мои файлы журналов почти всегда отмечены меткой времени, поэтому я добавил строку в файл примера:

2013-06-11 date stamped line

а затем он работает не так хорошо. Поэтому я вернулся к своему предыдущему регулярному выражению:

egrep --color '^\w*\b|bag' /tmp/barf

но строки, не связанные с датой, выявили проблемы с этим. Трудно это увидеть без раскраски...

Ответ 4

Следуя ответу @Steve, если вы хотите использовать другой разделитель (например, запятую), вы можете указать его, используя -F. Это будет полезно, если вы хотите, чтобы содержимое каждой строки было до первой запятой, например, при попытке прочитать значение первого поля в CSV файле.

$ awk -F "," '{print $1}' text1.txt > text2.txt