grep
には、検索文字列の正規表現の解釈をオフにする固定文字列オプション-F
(fgrep
)があります。 sed
に同様の機能はありますか?その男には何も見つかりませんでした。別のgnu/linuxツールの推奨も問題ありません。
検索と置換の機能にsed
を使用しています:sed -i "s/abc/def/g"
Sedを使用する必要がありますか? bashスクリプトを作成している場合は、次のことができます。
#!/bin/bash
pattern='abc'
replace='def'
file=/path/to/file
tmpfile="${TMPDIR:-/tmp}/$( basename "$file" ).$$"
while read -r line
do
echo "${line//$pattern/$replace}"
done < "$file" > "$tmpfile" && mv "$tmpfile" "$file"
古いBourneShell(ksh88やPOSIX shなど)では、それほどクールではない可能性があります${var/pattern/replace}
構造ですが、${var#pattern}
および${var%pattern}
、これを使用して文字列を分割し、再組み立てできます。それを行う必要がある場合は、さらに多くのコードが必要になりますが、それほど悪くはありません。
まだシェルスクリプトを使用していない場合は、パターン、置換、およびファイル名のパラメーターを非常に簡単に作成して、これを呼び出すことができます。 :)
PS- $ {TMPDIR:-/ tmp}構造体は、環境で設定されている場合は$ TMPDIRを使用し、変数が設定されていない場合は/ tmpを使用します。現在のプロセスのpidをファイル名の最後に貼り付けて、もう少しユニークになることを期待しています。 「現実の世界」ではおそらくmktempなどを使用する必要がありますが、これは簡単な例としては問題なく、mktempバイナリが常に利用できるとは限りません。
オプション1)正規表現文字をエスケープします。例えば。 sed 's/\$0\.0/0/g'
は、出現するすべての$ 0.0を0に置き換えます。
オプション2)quotemetaと組み合わせてPerl -p -e
を使用します。例えば。 Perl -p -e 's/\\./,/gi'
は、出現するすべての.
を,
に置き換えます。
次のようなスクリプトでオプション2を使用できます。
SEARCH="C++"
REPLACE="C#"
cat $FILELIST | Perl -p -e "s/\\Q$SEARCH\\E/$REPLACE/g" > $NEWLIST
もしあなたがしないでくださいあなたの文字列をエスケープしたいなら、
2つのステップで目標を達成できます。
fgrep
置換する行(行番号を取得)、
その後、この行を置き換えるためにsed
を使用します。
例えば.
#/bin/sh
PATTERN='foo*[)*abc' # we need it literal
LINENUMBER="$( fgrep -n "$PATTERN" "$FILE" | cut -d':' -f1 )"
NEWSTRING='my new string'
sed -i "${LINENUMBER}s/.*/$NEWSTRING/" "$FILE"
Rubyまたは長い行に反対しない場合は、次のように使用できます。
alias replace='Ruby -e "File.write(ARGV[0], File.read(ARGV[0]).gsub(ARGV[1], ARGV[2]))"'
replace test3.txt abc def
これにより、ファイル全体がメモリにロードされ、置換が実行されてディスクに保存されます。おそらく大量のファイルには使用しないでください。
_Perl -i.orig -pse 'while (($i = index($_,$s)) >= 0) { substr($_,$i,length($s), $r)}'--\
-s='$_REQUEST['\'old\'']' -r='$_REQUEST['\'new\'']' sample.txt
_
-i.orig
_バックアップによるインプレース変更。-p
_デフォルトで入力ファイルから行を出力します-s
_コマンドライン引数の基本的な解析を有効にする-e
_このスクリプトを実行するindex($_,$s)
_$s
_文字列を検索しますsubstr($_,$i,length($s), $r)
文字列を置き換えますwhile (($i = index($_,$s)) >= 0)
まで繰り返す--
_ Perlパラメーターの終わり-s='$_REQUEST['\'old\'']'
_、_-r='$_REQUEST['\'new\'']'
_-セット_$s
_、_$r
__'
_文字を「エスケープ」する必要がありますが、残りは簡単です。
注:これは 特殊文字文字列をsedに渡す方法 したがって_$_REQUEST['old']
_文字列への回答として始まりましたが、この質問はもう少し適切に定式化されています。
ファイル全体をメモリに読み込んでも問題がなければ、2行のbashコードでこれを行うことができます。これは非常に柔軟性があります。パターンと置換には、必要に応じて行間で一致する改行を含めることができます。また、read
を使用した単純なループでは保持されない、末尾の改行またはその欠如も保持します。
mapfile -d '' < file
printf '%s' "${MAPFILE//"$pat"/"$rep"}" > file
完全を期すために、ファイルにnullバイト(\0
)、上記を拡張する必要があり、
mapfile -d '' < <(cat file; printf '\0')
last=${MAPFILE[-1]}; unset "MAPFILE[-1]"
printf '%s\0' "${MAPFILE[@]//"$pat"/"$rep"}" > file
printf '%s' "${last//"$pat"/"$rep"}" >> file