次のファイルがあります。
1,2,subjects,\mat\hs,unix\,\Nato,\N,123,\N
\N を除くすべての \ を # に置き換えて、出力を次のようにしたいと思います。
1,2,subjects,#mat#hs,unix#,#Nato,\N,123,\N
次のsedコマンドを作成しようとしています。
sed -e 's@\\([^N])@#\1/g' filename
ただし、これはexの先頭に\ Nがあるすべての値に対して失敗します。\Nato
上記の例では。
私の要件を満たすsedコマンド(正規表現)を見つけるのに役立つ人はいますか?
答え1
私はあまり上手ではありませんsed
。ただし、これはperl
正規表現ツアーを使用して簡単に実行できます。
perl -pe 's/\\(?!N\b)/#/g' your_file_here
これにより、変更されたファイルが標準出力として印刷されます。交換するには、次のようにします。
perl -pi -e 's/\\(?!N\b)/#/g' your_file_here
デフォルトでは、これは従わないバックスラッシュN\b
(単語の境界にある文字N)に置き換えられます#
。
編集する
項目がコンマで区切られていると確信している場合は、次のようにして単語の終わりの大文字と\N
小文字を無視できます(SOLEM\N
提供された例のように)。
perl -pe ' s/\\/#/g; s/(\A|,)\s*#N\s*(\Z|,)/$1\\N$2/g;' your_file_here
バックスラッシュをハッシュトークンに置き換えてから、#N
2つのカンマの間、文字列の先頭とカンマの間、またはカンマと文字列の終わりの間で見つかったものを見つけます。
答え2
$ echo '1,2,subjects,\mat\hs,unix\,\Nato,\N,123,\N' \
| sed -r -e 's@\\([^N]|N[^,])@#\1@g'
1,2,subjects,#mat#hs,unix#,#Nato,\N,123,\N
編集する単語の大文字と小文字の一部である \N の場合: (コメントを参照)
$ echo '1,2,subjects,\mat\hs,unix\,\SOLEM\N,\N,123,\N' \
| sed -r -e 's@,\\N$@,:SINGLE_N_PLACEHOLDER:@g' \
-e 's@^\\N,@:SINGLE_N_PLACEHOLDER:,@g' \
-e 's@,\\N,@,:SINGLE_N_PLACEHOLDER:,@g' \
-e 's@\\@#@g' \
-e 's@:SINGLE_N_PLACEHOLDER:@\\N@g'
1,2,subjects,#mat#hs,unix#,#SOLEM#N,\N,123,\N
これは醜く信頼できません(プレースホルダ文字列は一意である必要があり、パターンがテキストに表示されると動作が停止します)しかし、sedが主張をサポートする方法でPCRE / Perlを使用できるようにする方法を見つけることができませんでした。
次のように短縮できます。
$ echo '1,2,subjects,\mat\hs,unix\,\SOLEM\N,\N,123,\N' \
| sed -r -e 's@\\@#@g' \
-e 's@(,|^)#N(,|$)@\1\\N\2@g'
1,2,subjects,#mat#hs,unix#,#SOLEM#N,\N,123,\N
ただし、この場合、文字列は#N
文字列に表示されないようにするプレースホルダです。
答え3
sed -e 's@\\\([^N]\|\(N[a-zA-Z]\|$\)\)@#\1@g' your_file_here
説明:\
以下をすべて交換してください。
- 何もありません
N
、 - または
N
その後に任意の文字が続きます[a-zA-Z]
(必要に応じて拡張可能) - 行末
#
と残りの一致パターンで。
答え4
$ echo '1,2,subjects,\mat\hs,unix\,\Nato,\N,123,\N' |
sed -r -e 's/\\N/XELI/g' |
sed -e 's/\\/#/g' |
sed -e 's/XELI/\\N/g'
1,2,subjects,#mat#hs,unix#,\Nato,\N,123,\N
分割する方が読みやすいと思います。
- \N を発生しない一部の文字に置き換えます。
- その後、/を#に置き換えます。
- / Nをもう一度交換してください。