web-dev-qa-db-ja.com

grep:最初の空白まで(含まない)までのすべての文字に一致

次の形式のテキストファイルがあります。

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

たとえば、次のとおりです。

foo garbagetext
hello moregarbage
keepthis removethis
(etc.)

そのため、Linuxでgrepコマンドを使用して、各行の文字のみを最初の空白スペースまで含めないようにしました。私は次のような多くの試みを試みました:

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

さまざまな例からつなぎ合わせようとしましたが、私には運がありませんでした。これらはすべて空のtext2.txtファイルを生成します。これは初めてです。何が間違っていますか?

*編集:

保持したい部分には大文字が含まれます。そのため、各行の空白を含めないで(すべての文字を空白から削除する)、すべての文字を保持します。

**編集:

(削除したい)ガベージテキストには、スペースや特殊文字など、何でも含めることができます。たとえば、次のようになります。

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
19
lord_sneed

量指定子*間違った場所。

代わりにこれを試してください:-

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

または、さらに良い:-

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

\Sは一致を意味します非空白文字。アンカー^は、行頭での一致に使用されます。

30
Rohit Jain

これはgrepソリューションで長い間回答されてきましたが、将来の世代では、この特定の状況には少なくとも2つのソリューションがあり、どちらもgrepよりも効率的であることに注意してください。

スペースで区切られた最初の列を取得するだけで、複雑なテキストパターンマッチングを行っていないため、awkやcutなど、列ベースのユーティリティを使用できます。

awkを使用

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

カットを使用

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

〜1.1MBファイルのベンチマーク

$ 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

awkgrepよりも約3倍高速で、cutはそれよりも約3倍高速です。繰り返しますが、1回の実行でこの小さなファイルに大きな違いはありませんが、再利用などのスクリプトを作成する場合や、大きなファイルで頻繁にこれを行う場合は、追加の効率性を高く評価するかもしれません。

13
Steve

@Steveによる回答をフォローアップし、別の区切り文字(コンマなど)を使用する場合は、-Fを使用して指定できます。これは、csvファイルの最初のフィールドの値を読み取ろうとする場合など、各行の内容を最初のコンマまでにする場合に役立ちます。

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

ログの行を「色付け」するために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

しかし、日付がスタンプされていない行は、thatの問題を明らかにしました。色付けせずにこれを見るのは難しいです...

0
MarkHu