改行を付けずにgrepを出力する


8

このスニペットを検討してください:

X=$(grep -m1 'some-pattern' some-file | sed -n 's/.* //p')

任意のテキストファイルの行でパターン条件が一致した場合、最後の単語を変数に入れたい

私の問題は、私がXやろうとしている後の操作を妨げるので、変数が最後にCRまたはLFまたはCRLFを持っていることです。
私は次のようなことも試しました:

X=$(grep -m1 'some-pattern' some-file | sed -n 's/.* \([A-Za-z]\+\)/\1/p')

したがって、sed出力が制限されることを期待してい[A-Za-z]+ますが、X変数内にはこの厄介なバイトが残っています。

どのように私が見るように、あまりにも多くのコードを使用せずに、それを取り除くことが可能と終わりに何バイトでxxd、その後cutそれと類似の合併症?

回答:


4

awkフィールドとレコードを使用できるため、これらの問題は存在しないため、ニーズに適した選択肢のように思われます。

x=$(awk '/some-pattern/ { sub(/\r$/, "") ; printf("%s", $NF) ; exit }' some-file)

置換により、CRLF行末の問題が回避されます。

sub(/\r$/, "")末尾のCRが存在する場合は削除します。はレコード(行)の区切り文字としてawk扱う\nので、調べているデータにはないので、それを取り除く必要はありません。

printf("%s", $NF)$NF末尾の改行なしで最後のフィールド()を出力します(print他の一部のawk関数はデフォルトで改行を追加します)。

exit最初の2つのアクションの後に発生m1します-これはgrepコマンドラインのと同じです。これによりawk、前の2つのコマンドの実行後に確実に終了します。これらのコマンドは一致時に発行され、awkはFIFO方式でデータを評価するため、最初の一致のみが出力されます。


ありがとう、それはエレガントに見えますが、残念ながらCRLF X
はまだ

:)今ではそれはもうエレガントに見えなくなり、それはまだ良くありません
zetah

@zetah-はありませんがCR、がありますLF。私はあなたが質問から何を望んでいるかを理解するのに苦労しました、うまくいけば私の編集はあなたが望んでいることをします。
クリスダウン、

OK、今度はうまくいきます-その行が何らかのパターン条件を満たす場合、行の最後の単語を出力します-わからない、多分私にはこの問題があり、ネイティブではない英語のスピーカーとして説明するのは難しいので、私には明らかです。とにかく、誰かがgrep/sed代わりにソリューションでこれに対処した場合awk(私には理解できません)、もう少し待って、そうでなければそれを使用します。ありがとう
zetah

@zetah-わかりやすく説明できるように、1秒間説明を追加します。
クリスダウン

7

``または$()末尾から改行を削除しますが、、プログラム的に使用し、これを行いますtr

grep -m1 'some-pattern' some-file | sed -n 's/.* //p' | tr -d '\012\015'

これにより、文字列からキャリッジリターンや改行が削除されます。

問題となるのは、結果をどのように出力するかです。たとえば、デフォルトでechoは、改行が追加されます。echo -nまたはを使用することができますprintf


これにより、文字列全体で発生する可能性があるキャリッジリターンも削除されます。
クリスダウン

はい、キャリッジリターンを1行に埋め込むことは可能ですが、非常にまれです。これ-m1により、出力が1つだけになることが保証されます。おそらく、最後に改行されます。
Arcege

ああtr...興味深い、LFとCRLFファイルの両方で動作します。\010\013どういうわけか、また\f\r正しく動作すると思います。結果について:私は実際には変数ではなく、で囲まれた変数として出力を入れていない$()ため、パターンにgrepマッチ- some pipe | grep -o " $(...) "。コメントをありがとう
zetah


2

これは私にとってはうまくいきます:

grep -m1 'some-pattern' some-file | sed -n 's/.* //p' | tr -d "\n" | tr -d "\r"

0

なぜ単純にクリーンアップをsed行わないのですか?[\r\f]

# using Bash's $'string' idiom (that decodes ANSI C escape sequences)
# cf. http://wiki.bash-hackers.org/syntax/quoting#ansi_c_like_strings
- X="$(grep -m1 'some-pattern' some-file | sed -n 's/.* //p')"
+ X="$(grep -m1 'some-pattern' some-file | sed -n -e $'s/[\r\f]*$//' -e 's/.* //p')"

2番目のアプローチには、末尾のCRをキャッチするための最後の正規表現がありません\r

# sample code to remove trailing \r with sed
# cf. http://en.wikipedia.org/wiki/Regular_expression#POSIX_character_classes
printf 'a b c\r' | sed -n 's/^.* \([[:alpha:]]\{1,\}\)/\1/p' | od -c
printf 'a b c\r' | sed -n 's/^.* \([[:alpha:]]\{1,\}\)[[:space:]]*/\1/p' | od -c

# keeps trailing space after c
printf 'a b c \r' | sed -n 's/^.* \([[:alpha:] ]\{1,\}\)[[:space:]]*/\1/p' | od -b

0

通常のバージョンのgrep(grep -Pを含む)は常に一致するラインフィードを出力するため、結果が1つしかない場合(または最後に追加されたラインフィードのみを削除する場合)は、最後の文字を削除するだけで十分です。出力のパイプラインを介して実行できますhead -c-1

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.