2016-05-30 1 views
0

名前の「重要でない」部分を置き換える必要があります。これはbashスクリプトで行う必要があります。これを行うには、 "VAN"、 "DEN"、 "DE"、 "DER"という中間語を削除する必要があります。

これを行うには、私は(問題が2行に減少)を交換ビルトインを使用しています:

line="STIG VAN DE WYNKELE"; 
line=${line//@(' VAN '|' DEN '|' DE '|' DER ')/' '}; 
echo $line; 

出力:

STIG DE WYNKELE 

予想される出力:

STIG WYNKELE 

@(...)は中間の単語の1つにマッチしていて、この1つの中間語のすべての出現を取り除いているようですが、それ以外は一致しませんrs。

質問:私の構文が間違っていますか?そうでない場合は、どうすればその言葉を削除できますか? sedはファイルを必要とし、入力は変数であり、変更されたテキストも変数に格納する必要があります。 ($行を変更する必要があります)

+1

は 'sed'ファイルを必要としない、それはストリームエディタです。 'foo = $(echo" $ foo "| sed ...)'は一般的なイディオムです。 –

+0

一般的ですが、 '$ foo'が短い場合は通常不要です。 – chepner

答えて

3

bash後戻りしません。まず、入力にVANを発見:

STIG VAN DE WYNKELE 
    ^^^^^| 

(走査しながら|は、そのポインタを表します)。

VANを交換した後、あなたは

STIG DE WYNKELE 
    | 

を持っているあなたはDから始まるDEが文字列で発見されていないことに気づくでしょう。挿入したスペースはbashでチェックされません。

代わりに、各パターンから先頭のスペースを削除し、代わりにスペースでそれを置き換えるの一致を削除します。もちろん

echo "${line//@('VAN '|'DEN '|'DE '|'DER ')}" 

を、これに伴う問題は、あなたが今落とすかもしれないということです単語の終わりに起こる一致。 1つの試合でそれを避けることはできません。ループ内で複数の置換を行う:

for word in VAN DEN DE DER; do 
    line=${line// $word/} 
done 
+0

これは問題を解決し、副作用なしでそれを行うための最善の方法のようです、ありがとう! – Bertware

+0

単一のマッチでは可能ですが、ルックアラウンド(bashではサポートされていません)のみで可能です。 – choroba

0

extglobのパターンは必要ありません。あなただけのパラメータ展開を使用することができます。

${line/ */} 

例:

$ line="STIG VAN DE WYNKELE" 
$ echo ${line/ */} 
STIG WYNKELE 
4

extglobオプションを設定する必要があります。また、引用符を削除し、スペースを別の場所の外に移動します。あなたは、さらに表現を短縮することができます。

#!/bin/bash 
line="STIG VAN DE DEN DER WYNKELE" 
shopt -s extglob 
line=${line//@(VAN|DE?([NR])) } 
echo "$line" 

最後の行でダブルquotting $行することで、あなたはスペースが正しく削除されたかどうかを確認することができます。AWKで

+0

「必要」は強い言葉です。ここで 'extglob'を使う必要はありません – hek2mgl

+0

@ hek2mgl:' @(... | ...) 'を使うためには、あなたは... – choroba

+0

あなたはそうです、私はそれを見落としました。私のボックスでデフォルトで有効になっています..ありがとう! – hek2mgl

0

echo $line | awk '{ if ($2 == "VAN" || $2 == "DEN" || $2 =="DE" || $2=="DER" ) $2=""; if ($3 == "VAN" || $3== "DEN" || $3 =="DE" || $3=="DER" ) $3="" ; print }' 
関連する問題