sedは、入力がファイルの代わりにエコーから来るときに機能します。

sedは、入力がファイルの代わりにエコーから来るときに機能します。

以下は、電子メールアドレス文字列の周りの引用符を削除します。

$ echo  "[email protected]" | sed 's/"([^"]*)"/\0/g'  
[email protected]  

しかし、もし:

$ cat ~/Desktop/emails.txt 
"[email protected]"  
$ sed 's/"([^"]*)"/\0/g' ~/Desktop/emails.txt    
"[email protected]"   
$ sed -i '' 's/"([^"]*)"/\0/g' ~/Desktop/emails.txt
$ cat ~/Desktop/emails.txt 
"[email protected]"  

同じ文字列を含むファイルを使用してまったく同じsed正規表現置換を適用しようとすると、機能しません。
私は何が間違っていましたか?

答え1

申し訳ありません。あなたのecho例はうまくいきません。二重引用符(")は解釈され渡さbashれないため、機能しているようですsed

次の2つの例の違いを確認してください。

$ echo "[email protected]" 
[email protected]
$ echo "\"[email protected]\"" 
"[email protected]"

あなたのechoコマンドは提供されていないので、削除する入力文字列に何もないので"動作するようです。sed"

"この例は、正しくエスケープしようとするとecho機能しませんfile

$ echo  "\"[email protected]\"" | sed 's/"([^"]*)"/\0/g'  
"[email protected]"

コマンドsedには2つのエラーがあります。

  1. 拡張正規表現構文を使用しています。 sedがある場合にのみ使用できますgnu。違いは括弧を使用する方法です。
  2. で始まる逆参照を計算する必要があります1

したがって、正しいコマンドは次のようになります。

echo  "\"[email protected]\"" | sed 's/"\([^"]*\)"/\1/g' 

またはsed拡張正規表現をサポートする場合:

echo "\"[email protected]\"" | sed -E 's/"([^"]*)"/\1/g'

答え2

gv@debian:$ cat a.txt
"[email protected]"

gv@debian:$ sed 's#"##g' a.txt #remove all quotes
[email protected]

gv@debian:$ cat a.txt |tr -d '"' #remove all quotes
[email protected]

gv@debian:$ sed 's#^"##g; s#"$##g' a.txt #remove first and last quote 
[email protected]

gv@debian:$ a="\"[email protected]\"";echo -e "$a" "\n" "${a: 1:-1}" #remove first and last char
"[email protected]" 
 [email protected]

答え3

@andcozが述べたように、これは

$ sed -i '' 's/"([^"]*)"/\0/g' ~/Desktop/emails.txt

parenthesesエスケープ処理してからbackreferenceに変更する必要があります。\0\1

修正後の関数sedコマンドは次のようになります。

$ sed -i '' 's/"\([^"]*\)"/\1/g' ~/Desktop/emails.txt  

関連情報