【问题标题】:Colons are not being printed correctly没有正确打印冒号
【发布时间】:2018-03-16 04:05:01
【问题描述】:

注意:我对 bash 了解不多。很抱歉,如果答案很明显。

我正在尝试制作一个从文件中逐字符打印文本的脚本。这样做时,我注意到冒号 (:) 出于某种原因被 Illegal option -: ? 替换。 我不知道为什么会发生这种情况或如何阻止它发生,这就是我在这里的原因。

代码(我从一个 stackoverflow 问题中得到了一些,也添加了一些我自己的):

#!/bin/sh
value=`cat $1`
iterate_over_chars()
{
    local seq="$1" OPTIND=1
    while getopts "$seq" opt "-$seq"; do
        echo -n "$opt"
        sleep 0.025
    done
}
iterate_over_chars "$value"
echo
echo
echo
echo END

要运行它,我输入

sh name.sh test.txt test.txt:

test says: HI

输出是

pi@raspberrypi:~ $ sh credits.sh test.txt
test saysIllegal option -:
? HI


END

还将 echo -n "$opt" 更改为 echo -ne "$opt" 在字符前面打印 -ne,而不是使用参数 n 和 e。这是有原因的吗?

【问题讨论】:

  • getopts 不是遍历字符的好方法。几个字符(包括“:”)对它有特殊的含义,并且可以使这个构造失败。
  • 好吧,我使用更好的替代方案修复了脚本。谢谢
  • 以及为什么echo -anything 是不可预测的,请参阅unix.stackexchange.com/questions/65803/…

标签: bash shell unix


【解决方案1】:

我也会避免使用getopts。 Bash 有多种参数扩展,它们是一种更原生的字符串操作方式。在这种情况下,${s:0:1} 可用于捕获字符串 s 的第一个字符,${s#?} 用于发出除该字符串的第一个字符之外的所有字符。

这是使用这些表单的一种方式。我还在while循环中通过read内置函数一次读取一行文件,而不是使用反引号捕获cat的输出。

#!/usr/bin/env bash

[ $# -eq 1 ] || { echo "Usage: ${0##*/} <file>" 1>&2; exit 1; }
[ -r "$1" ] || { echo "$1: cannot read" 1>&2; exit 1; }

iterate_over_chars() {
  local s="$1"
  while [ "$s" != '' ]; do
    echo -n "${s:0:1}"
    s=${s#?}
    sleep 0.025
  done
  echo
}

while IFS= read -r line; do
  iterate_over_chars "$line"
done < "$1"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-25
    • 1970-01-01
    • 2015-08-07
    • 1970-01-01
    • 1970-01-01
    • 2020-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多