Bash 保存一个 tr 操作的字符串

Bash saving a tr manipulated String

我有一个小程序可以询问用户的名字和姓氏。我需要将给定姓氏的最后一个字符更改为名字和姓氏中的下划线(以及在字符串中进一步出现的任何字符)。我还需要将用户的名字更改为大写字母。我得到了这部分代码,我在其中操作给定的字符串。

echo -n "Hello "
X="$X" | tr ${Y:(-1)} "_"
echo -n "${X^^}"
echo " $Y" | tr ${Y:(-1)} "_"

出于某种原因,第 2 行:X="$X" | tr ${Y:(-1)} "_" 没有像我想要的那样保存变量。例如,当我填写 "Cannon Nikkon" 程序时 returns "Hello CANNON Nikko_"。但是当我打印 echo "$X" | tr ${Y:(-1)} "_" 时,它会打印 "Hello Ca__o_ Nikko_"。我试图通过写 echo "${X^^}" | tr ${Y:(-1)} "_" 来解决它,但它仍然返回 "Hello CANNON Nikko_"。我想通了,因为 n 和 N 不是相同的字符,所以它不会改变。

但是为什么不保存第2行的变量呢?我需要如何解决这个问题?

如果我没理解错的话, 而不是这个:

X="$X" | tr ${Y:(-1)} "_"

您想这样做:

X=$(tr ${Y:(-1)} "_" <<< "$X")

也就是说,您想将 tr 的输出写回 X。 原来的声明根本没有这样做, 它做了完全不同的事情:

  1. X的值设为"$X"
  2. 将赋值的输出(无)传送到 tr

打印了tr的输出,X中没有保存, 与你可能相信的相反。

使用正确的工具更改字符串${//}

first="jason";
echo "${first/%?/_}"     ### Using % means: "at the end of the string".

完整的更改将是:

first="jason";
first="${first/%?/_}"
first="${first^}"              ### Use ^^ to change all the string.
echo "$first"

并且,询问用户将是:

#!/bin/bash
read -rp "Your first name, please: ? " first
read -rp "Your Last  name, please: ? " last
first="${first/%?/_}"
first="${first^}"
last="${last/%?/_}"
last="${last^}"
echo "$first $last"