ファイルの任意の場所にある文字を置き換えようとしています。私のファイルは次のとおりです。
aab
babab
abab
「c」を任意の文字に置き換えようとしています。したがって、出力は次のようになります。
aab
bcbab
abab
すべての改行を削除し、new_string.txtファイルに保存してからsedを試しましたが、うまくいきませんでした。
これは私が試したコードです。
rand1="$(shuf -i 0-$tot_len -n 1)"
sed "s/^\(.\{"${rand1}"\}\)./\1G/" new_string.txt
継続エラーが発生します。
sed: -e expression #1, char 25: Invalid content of \{\}
答え1
変数には中括弧は必要なく、変数も引用符で囲む必要があります。使用:
sed "s/^\(.\{$rand1\}\)./\1G/" new_string.txt
アップデート:コメントで述べたように:
元のコードは問題ありませんが、整数が大き$rand1
すぎますsed
。可能な最大値は32767
GNUでsed
あり、sed
まだ16ビット整数のみが必要であることがわかりました。
これにより、システム正規表現ライブラリの制限を得ることができます(GNUはsed
通常組み込みバージョンを使用しますが)。
$ getconf RE_DUP_MAX
32767
POSIXでは、この制限は少なくとも_POSIX_RE_DUP_MAX
255でなければなりません。これは移植性を期待できる最大値です(一部のシステム(SolarisやOS / Xなど)にはこれらの制限があります)。
答え2
GNUシステムで文字(改行を除く)をランダムに置き換えるには、次のようにします。
file=myfile.txt
offset=$(grep -bo . < "$file" | cut -d: -f1 | shuf -n1)
[ -z "$offset" ] || # file doesn't have non-newline characters
printf c | dd bs=1 seek="$offset" of="$file" conv=notrunc status=none
(以前のバージョンのGNU dd
(8.20より前)の場合status=none
に置き換えてください2> /dev/null
。)
grep -bo . < "$file"
ファイルの改行文字ではなく、各文字のバイトオフセットを提供します。たとえば、UTF-8でエンコードされたファイルには次のものが含まれます。
$3
£1
€2
これは私たちに以下を提供します。
$ grep -bo . < "$file"
0:$
1:3
3:£
5:1
7:€
10:2
の場合、cut -d: -f1
最初のコロンの前の部分を維持します。次に、これらのオフセットの1つをランダムに選択しますshuf -n1
。
これは、置換文字が置換される文字と同じサイズであると仮定する。たとえば、上記の£(2バイト)をc(1バイト)に置き換えると、ファイルの後にc
誤った文字が表示されます。
この問題を解決するにはデータを移動する必要があるため、ファイルを上書きすることはできません。
次のようなものが必要です。
perl -C -0777 -pi -e "substr \$_, $offset, 1, 'c'" -- "$file"
代わりに。とともに-C
、perl
コンポジションのロケールを尊重します。特徴。-0777 -p
開いている喫煙内容物を$file
飲み込むモード$_
(参照:perl -ne '...'実行のセキュリティリスク*この建設の安全問題のため)。コードの実行後にファイルに書き換える-pi
内部編集機能を提供します。次に、指定されたオフセットで1文字の置換を$_
呼び出します。substr
c
答え3
\n
新しいGNU sedを使用すると、ewlineを削除せずにこれを行うことができます。
sed -z "s/./@/$(($RANDOM%$(wc -m < file.txt)))" file.txt
答え4
この試み:
sed 's/^\(.\{'"${rand1}"'\}\)./\1G/' new_string.txt