2012-06-29 12 views

答えて

23

を使用するように、このためのsedなどの外部ツールを使用する理由はありません、それは大文字と小文字が区別されることに注意してください。 bashは、内部using parameter expansionそれを行うことができます。

あなたが後にトリミングしたい文字は、例えば、:の場合:

$ str=foo_bar:baz 
$ echo "${str%%:*}" 
foo_bar 

あなたは貪欲と非貪欲両方の方法でこれを行うことができます:

$ str=foo_bar:baz:qux 
$ echo "${str%:*}" 
foo_bar:baz 
$ echo "${str%%:*}" 
foo_bar 

特に、タイトなループの中でこれを呼び出す場合は、新しいsedプロセスを開始し、プロセスに書き込んだり、その出力を読み込んだり、終了するのを待って(PIDを取得したりする)内部処理のbash wそれはありません。


は今 - これをやりたいと思ったときに、多くの場合、あなたが本当にたい場合がありますことは、より良いreadで行われるフィールドに変数を分割することです。例えば

は、あなたは/etc/passwdから行を読んでいるとしましょう:あなたは、ファイルから複数の行を処理したい場合でも

line=root:x:0:0:root:/root:/bin/bash 
IFS=: read -r name password_hashed uid gid fullname homedir shell _ <<<"$line" 
echo "$name" # will emit "root" 
echo "$shell" # will emit "/bin/bash" 

、これはあまりにも一人ではbashを使って行うことができ、外部プロセス:

while read -r; do 
    echo "${REPLY%%:*}" 
done <file 

は...任意の内線を必要とせずに、fileの各ラインから最初の:にすべてを放出しないだろう時代遅れのツールを立ち上げる。

8

あなたが探しているが、実際には本当に簡単です:

Aは、特定の文字をマーク
sed 's/A.*//' 

。あなたが複数の文字をキャッチしたい場合は

sed 's/[aAbB].*//' 
2

TEXTは

TEXT=beforexafter 

のように、あなたのテキストが含まれており、特定の文字がxする(たとえば)発生した場合、その後、

echo "${TEXT%x*}" 

は何をしたいん。 bashに

"$TEXT"または"${TEXT}"は全体beforexafterですが、xafterは終わりを切り落として"${TEXT%xafter}"は、ちょうどbeforeです。 xとそれに続く可能性のあるものを切り詰めるには、"${TEXT%x*}"と書いてあります。

偶然にも"${TEXT%%x*}"があります。これは、1つ以上のxがある場合にのみ、他とは異なります。 %%では、Bashはすべてxを切り捨てますが、%では最後のxから切り捨てられます。 %%が長いほど、より多くのテキストが切り捨てられることをゆるやかに観察することで、これを覚えておくことができます。

希望する場合は、もちろん、sedのと同様に行うことができます。

echo "$TEXT" | sed 's/x.*//' 
+2

展開の前後に引用符を入れてください - 'TEXT'は' $が含まれている 'ので、もしエコー$ TEXT'は、文字列の分割を行います'foo \ t \ tbar \ nbaz''の場合、 'foo bar baz'というだけで出力されますが、' echo "$ TEXT"はこの欠陥を表示しません。 (全面的な非環境変数を永続化することは少し残念ですが、環境変数や組み込み関数との名前空間の競合を避けるため、小文字にしておくのがベストプラクティスです)。 –

+0

@CharlesDuffy:あなたは引用については正しいです:それらを省略すると、私は今から改革すべき悪い習慣です。オールカップについては、さらに興味深い説明をして興味深い点を作っています。私は帽子に関するあなたのアドバイスが良いと思う。 – thb

+1

質問はありませんが、関連しています。 'after'を実行するには' echo "$ {TEXT#* x}" ' –

関連する問題