tr
是一个很棒的工具,可以用来翻译set of characters
成另一个set of characters
.
诸如此类的命令sed , awk, perl
可用于翻译set of characters
成另一个一组字符串,例如,它可以翻译<
和>
进入 <
和>
,但似乎没有必要为此目的使用这些命令!
还有其他命令可以完成此任务吗?
答案1
我不知道你使用的是哪个 shell,但很可能tr
不是内置的。在 bash 或 zsh 中肯定不适合我:) 尝试运行type tr
自己看看。
很可能sed
是适合这项工作的工具。这就是它的用途。酌情perl
而awk
也。
如果您的情况非常简单,并且您正在使用字符串变量而不是管道,那么您可能会使用真正的内置函数,例如使用 bash 的字符串搜索和替换变量。
string="Stuf with <tag> in it."
escaped=${string//</<}
escaped=${escaped//>/>}
echo $escaped
答案2
如果您想使用标准参数处理,则用另一组多个字符串替换多个字符串会变得很混乱。通常,命令采用一组原子参数,然后是一组原子参数,除了参数在参数之后(--
如果不明确,则用 分隔)之外,顺序并不重要。在这种情况下,你将如何构建概要?
这是一个简单的函数,可以完成简单的替换:
$ trs() {
local string=$1
shift
for replacement in "$@"
do
string="$(sed -e "s/$replacement/g" <<< "$string")"
done
printf "$string"
}
$ trs '1 2 3' '1/foo' '2 3/bar baz'
foo bar baz
或者,您可以使用参数对:
$ trs() {
local string=$1
shift
while [ $# -gt 0 ]
do
string="$(sed -e "s/$1/$2/g" <<< "$string")"
shift 2
done
printf "$string"
}
$ trs '1 2 3' 1 foo '2 3' 'bar baz'
foo bar baz
答案3
sed
可能很可怕,但是简单的字符到字符串替换sed
并不是真的太糟糕。
要替换x
为字符串bar
,请执行以下操作:
{something-that-outputs-something-on-stdout} | sed -e 's/x/bar/g'
如果这是您要处理的文件,您可以使用:
sed -e 's/x/bar/g' {filename}
(末尾的“g”表示“全局”,这意味着替换该行中的所有出现项,而不仅仅是第一个)
答案4
如果您知道较长的字符串是什么,那么sed -e s/xx/yy/g
答案就是可靠的。
但是,如果您希望更通用并接受任何字符串作为输入,例如来自函数参数的字符串,则不能使用 sed:您必须在正则表达式中使用字符串之前对字符串进行转义,这非常困难。
为了更可靠地做到这一点,您可以使用这个 oneliner:
python -c '(lambda s: s.stdout.write(s.stdin.read().replace(*s.argv[1:])))(__import__("sys"))'
将其添加为 .bashrc 中的别名以方便使用:
alias trs='python -c '\''(lambda s: s.stdout.write(s.stdin.read().replace(*s.argv[1:])))(__import__("sys"))'\'''
和:
$ echo /some-path/file | trs -path /dir1/dir2
/some/dir1/dir2/file
背景:我用它作为另一个别名;cds
,模拟 zsh 的“cd foo bar”行为,替换foo
您bar
的 pwd 中的:
$ function cds { cd "$(pwd | trs "$1" "$2")" ; }
$ mkdir -p /tmp/foo /tmp/bar
$ cd /tmp/foo
$ cds foo bar
$ pwd
/tmp/bar
sed
如果我传递了/
, 或其他非正则表达式安全字符,则这不适用于某个版本。