sedで冗長置換を避ける方法は?

sedで冗長置換を避ける方法は?

最初のファイルには以下が含まれます。

#. This is the file name to process: waveheight.txt
#. This is the latest data to process if exists: waveheightNew.txt
 FilNam=Project2128/Input/waveheightNew.txt
 if [[ ! -f ${FilNam} ]]; then FilNam=Project2128/Input/waveheight.txt; fi

2番目のファイルには次のものが含まれます。

#. This is the file name to process: waveheightBin.txt
#. This is the latest data to process if exists: waveheightNewBin.txt
 FilNam=Project2128/Input/waveheightNewBin.txt
 if [[ ! -f ${FilNam} ]]; then FilNam=Project2128/Input/waveheightBin.txt; fi

.txtBin.txt今、?に変更してファイルを処理する必要があります。を使用すると、2番目のファイルがsed "s/.txt/Bin.txt/"生成されます。その時BinBin.txt頃だったらぎこちなく見えたはずです。sed "s/Bin.txt/.txt/"sed "s/.txt/Bin.txt/"

不要な試合はスキップする方が賢明でしょうか?

答え1

Binテキストに置き換えたい項目がある場合は、それを含めるとその項目自体が置き換えられます。

sed 's/\(Bin\)\{0,1\}\.txt/Bin.txt/g'

またはsedEREをサポートしている場合-E(または-rいくつかの以前のバージョンのGNUまたはbusybox sed):

sed -E 's/(Bin)?\.txt/Bin.txt/g'

Bewareは、.すべての単一文字に一致する正規表現演算子です。\.テキストを一致させる必要があります。指す

答え2

Perl Negative LookBehindを使用して一致させることはできますが、.txtそうではありませんBin.txt

perl -pe 's/(?<!Bin)\.txt/Bin.txt/g'

したがって、テストするには、次の手順を実行します。

$ echo 'Bin.txt foo.txt' | perl -pe 's/(?<!Bin)\.txt/Bin.txt/g'
Bin.txt fooBin.txt

残念ながら、sedこの構成は提供されません。

答え3

を使用して条件付き置換を実行できますsed。たとえば、行がすでに含まれているかどうかをテストし、含まれていBin.txtない場合にのみ置換を実行できます。

sed '/Bin\.txt/!s/\.txt/Bin.txt/'

これは、行ごとに1つの置換のみが必要であると仮定します。

質問にヒントを与えましたが、同じ呼び出し内で無条件置換を実行し、エラーがある場合は修正することもできますsed

sed -e 's/\.txt/Bin.txt/' -e 's/BinBin/Bin/'

答え4

GNU-sed次のようにこれを行うことができます。

echo "$Filnam" |\
sed -e '
   s/\.txt/\n&/;T   # try to place a newline marker to the left of .txt, quit if unsuccessful
   s/Bin\n/Bin/;t   # If the marker turned out to be just to the right of Bin => Bin.txt already 
                    # existed in the name, so we needn"t do anything n take away the marker n quit
   s/\n/Bin/        # Bin could not be found adjacent to .txt so put it n take away the marker as well
'

### Below is the POSIX sed code for accomplishing the same:
sed -e '
    s/\.txt/\
&/;/\n/!b
    s/Bin\n/Bin/;/\n/!b
    s/\n/Bin/
'

関連情報