【问题标题】:Bash: echoing variable with spaces overlapping stringBash:用空格重叠字符串回显变量
【发布时间】:2014-04-22 02:05:32
【问题描述】:

我正在寻找变量中的特定行,例如

echo "$CodeDesc"

0x19 ERASE(6)
0x1A MODE SENSE(6)
0x1B START STOP UNIT
0x1C RECEIVE DIAGNOSTIC RESULTS
0x1D SEND DIAGNOSTIC
0x1E PREVENT ALLOW MEDIUM REMOVAL
0x23 READ FORMAT CAPACITIES
0x24 SET WINDOW

例如如果我只是在寻找“MODE SENSE(6)”,我正在使用 grep 和 awk(也尝试使用 sed)

desc="$( grep "0x1A" <<< "$CodeDesc" | awk '{print substr($0, index($0,$2))}' )"

这确实给了我正确的字符串,即“MODE SENSE(6)”,但是当我回显时,它与一些字符串重叠:

echo "DESC: \"$desc\""

给我:

  "SC:"MODE SENSE(6)

请注意 \" 已移到开头,并且缺少 DE。

稍后我还将打印同一个变量以及另一个变量:

echo -e "${desc}${code}"

我希望这会打印出来:

MORE SENSE(6) 0x1A 1

但是我得到了:

 0x1a 1NSE(6)

我不知道这是怎么回事,任何帮助将不胜感激。

【问题讨论】:

  • 看起来你有一个没有 LF 的 CR。
  • 你从哪里得到字符串?如果它来自一个文件,它可能有奇怪的字符。要“清理”它,您可以使用dos2unix

标签: bash


【解决方案1】:

显然您的$CodeDesc 是由以CRLF 终止的行组成的字符串。 grepawk 忠实地保留了行尾,而 shell 的 $() 替换会去掉最后的 LF,留下一个以 CR 结尾的字符串。

打印 CR 时,光标移动到行首,接下来打印的内容将覆盖原来的内容。

您可以通过在管道中添加| tr -d '\015' 来解决此问题,或者您可以在awk 中完成所有操作,包括grep 部分:

desc="$(awk '{gsub(/\r/,"")} /0x1A/ {print substr($0, index($0,$2))}' <<< "$CodeDesc")"

【讨论】:

  • 它看起来甚至比这更奇怪——在我看来,它就像有一个回车,然后是一个空格,然后是(正常的)换行符。删除 CR 可能会也可能不会完全解决问题。此外,Brian 最好首先找出这些垃圾字符的来源。
  • 感谢您的提示,| tr -d '\015 对问题进行了排序。 @Gordon,我最初是在做 wget 来获取代码/描述,我只过滤掉代码和描述
【解决方案2】:

这里不需要 awks 和 grep。

Bash 版本 > v4:

declare -A codes

while read -r code desc; do
    codes["$code"]=$desc
done <<< "$CodeDesc"

printf 'DESC: "%s"' "${codes['0x1A']}"

Bash 版本

while read -r code desc; do
    [[ $code = '0x1A' ]] && printf 'DESC: "%s"' "$desc"
done <<< "$CodeDesc"

【讨论】:

  • 感谢吉拉德的回复,我没想过做地图,上述解决方案解决了我的具体问题,因此被接受为答案
  • 很好的答案。如果我是问题的作者,我会接受你的回复
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-23
  • 2014-06-11
  • 1970-01-01
  • 2022-11-02
  • 2013-09-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多