如何使用'sed'来更改bash脚本中的变量?

如何使用'sed'来更改bash脚本中的变量?,bash,sed,Bash,Sed,我正在尝试使用enscript从Mutt打印PDF,并解决字符编码问题。一种解决方法似乎是使用sed来替换问题字符:sed-ir的//[“”]//g'{input} 我的测试输入文件如下: “very dirty” we’re 我希望弄得很脏,但我还是会弄得脏兮兮的 â\200\234very dirtyâ\200\235 weâ\200\231re 我找到了一个不错的小帖子,我把它作为一个起点。我有一个bash脚本,我使用set print_command=$HOME/.mutt

我正在尝试使用enscript从Mutt打印PDF,并解决字符编码问题。一种解决方法似乎是使用sed来替换问题字符:sed-ir的//[“”]//g'{input}

我的测试输入文件如下:

“very dirty”    
we’re 
我希望弄得很脏,但我还是会弄得脏兮兮的

â\200\234very dirtyâ\200\235
weâ\200\231re
我找到了一个不错的小帖子,我把它作为一个起点。我有一个bash脚本,我使用set print_command=$HOME/.mutt/print.sh从.muttrc指向它-该脚本当前的内容如下:

#!/bin/bash
input="$1" pdir="$HOME/Desktop" open_pdf=evince


# Straighten out curly quotes

sed -ir 's/[“”]/"/g' $input
sed -ir "s/[’]/'/g" $input


tmpfile="`mktemp $pdir/mutt_XXXXXXXX.pdf`"
enscript --font=Courier8 $input -2r --word-wrap --fancy-header=mutt -p - 2>/dev/null | ps2pdf - $tmpfile
$open_pdf $tmpfile >/dev/null 2>&1 &
sleep 1
rm $tmpfile
它在创建PDF方面做得很好,如果你给它一个文件作为参数,它也可以很好地工作,但是我不知道如何修复卷曲的引号

我在sed线上尝试了一系列变化:

根据当时的建议,我还尝试了input=$sed-r的//[“”]//g'来编辑变量 是关于在bash中执行搜索和替换操作(包括在变量内)的综合参考,因此建议阅读。关于这一特殊情况:

改用shell的本机字符串操作;这比分叉子shell、在其中启动外部进程并读取外部进程的输出要高得多。详细介绍了这个主题,非常值得一读

根据bash的版本和配置的区域设置,可以像原始代码那样使用括号表达式ie.[“”]。然而,最可移植的方法是将“和”分开处理,即使没有多字节字符支持,这也可以工作

input='“hello ’cruel’ world”'
input=${input//'“'/'"'}
input=${input//'”'/'"'}
input=${input//'’'/"'"}
printf '%s\n' "$input"
…正确输出:

"hello 'cruel' world"
论sed的使用 为了提供一个直截了当的答案,您的问题中几乎有一个基于sed的有效方法

input=$(sed -r 's/[“”]/"/g' <<<"$input")
…在$input的参数扩展周围添加缺少的语法双引号,确保它被视为单个标记,而不管它是字符串拆分还是全局扩展

但这一切可能都无济于事。。。 之所以提到以下内容,是因为您的测试脚本正在处理在命令行上传递的内容;如果在生产中不是这样,您可以忽略以下内容

如果您的脚本被调用为./yourscript“hello*'craul'*world”,那么在脚本启动之前,有关用户输入内容的确切信息将丢失,您在此处所做的任何操作都无法修复该问题


这是因为在该场景中,$1将只包含“hello;'craul'和world”在它们自己的argv位置,并且*s将被替换为当前目录中的文件列表,在脚本启动之前,每个这样的文件都被替换为单独的参数。因为负责解析用户命令行的shell与运行脚本的shell不同!在脚本运行此解析时,没有识别出引号是有效的,在脚本运行时,您无法恢复原始数据。

摘要:探索了使用sed更改变量的方法,但您真正需要的是使用和编辑文件的方法。前面有报道

塞德 这两行sed可以通过以下注释来解决:未使用-i,它不是一个文件,而是一个值:

input='“very dirty”    
we’re'

sed 's/[“”]/\"/g;s/’/'\''/g' <<<"$input"
$1 但是您的脚本存在一个潜在的问题,您正在尝试清除从命令行接收的输入。您正在使用$1作为字符串的源。一旦有人写道:

./script  “very dirty”    
we’re
该输入丢失。它被分解成壳牌的代币,1美元将是“非常有限的”

但我不相信这是你真正拥有的

文件 但是,您也在说输入来自文件。如果是这种情况,请使用以下命令读入:

input="$(<infile)"           # not $1

sed 's/[“”]/\"/g;s/’/'\''/g' <<<"$input"
您可以使用:

infile="$1"
sed -i 's/[“”]/\"/g;s/’/'\''/g' "$infile"
input="$(<"$infile")"
然后,整个脚本将在bash或sh中运行:

#!/usr/bin/env bash
Usage(){ echo "$0; This script require a source file"; exit 1; }
[ $# -lt 1 ] && Usage
[ ! -e $1 ] && Usage
infile="$1"
pdir="$HOME/Desktop"
open_pdf=evince

# Straighten out curly quotes
sed -i 's/[“”]/\"/g;s/’/'\''/g' "$infile"

tmpfile="$(mktemp "$pdir"/mutt_XXXXXXXX.pdf)"
outfile="${tmpfile%.*}.ps"
enscript --font=Courier10 "$infile" -2r \
     --word-wrap --fancy-header=mutt -p "$outfile"

ps2pdf "$outfile" "$tmpfile"

"$open_pdf" "$tmpfile" >/dev/null 2>&1 &
sleep 5
rm "$tmpfile" "$outfile"

也许你需要设置你的语言环境。注意,如果你希望这些引文实际上影响了如何对参数进行分组,即要具有语义意义,那么在脚本启动后修复它已经太晚了——它们已经被视为文字的而不是句法的。环境变量名称,所有大写名称保留用于修改系统或外壳行为的变量,而至少具有一个小写字符的名称保留用于应用程序。由于使用与环境变量重叠的名称设置外壳变量会覆盖后者,因此这些约定必然适用于两个pl你也可以考虑通过@ StAdAutoR运行代码,我会编辑它,但是它在命令行工作得很好。altering@sorontar,当然-但是如果标题问如何修改变量,这就是我要回答的,因为任何想知道如何修改变量的人都会看到该标题并来到q我希望这会有所帮助。也就是说,你有一个很好的答案,我很高兴他们都在这里。我想你的意思是美元,不是@@
查理·杜夫!是的,这就是我的意思,编辑,谢谢。很有趣。如果我像你建议的那样从命令行运行它,这很好,但是当我从Mutt运行它时,它就不起作用了。马特说,这条消息不可能是真实的printed@Amanda很抱歉,从Mutt开始工作是一个全新的问题。请问一下。
sed -i 's/[“”]/\"/g;s/’/'\''/g' infile
input="$(<infile)"
./script infile
infile="$1"
sed -i 's/[“”]/\"/g;s/’/'\''/g' "$infile"
input="$(<"$infile")"
./script infile
#!/usr/bin/env bash
Usage(){ echo "$0; This script require a source file"; exit 1; }
[ $# -lt 1 ] && Usage
[ ! -e $1 ] && Usage
infile="$1"
pdir="$HOME/Desktop"
open_pdf=evince

# Straighten out curly quotes
sed -i 's/[“”]/\"/g;s/’/'\''/g' "$infile"

tmpfile="$(mktemp "$pdir"/mutt_XXXXXXXX.pdf)"
outfile="${tmpfile%.*}.ps"
enscript --font=Courier10 "$infile" -2r \
     --word-wrap --fancy-header=mutt -p "$outfile"

ps2pdf "$outfile" "$tmpfile"

"$open_pdf" "$tmpfile" >/dev/null 2>&1 &
sleep 5
rm "$tmpfile" "$outfile"