如何在bash

时间:2018-03-13 15:59:18

标签: bash shell printf string-formatting

对我来说一直是一个烦恼(轻微但不变)是我无法(或者不知道如何)在bash代码中将字符串分割成多行。我有这个:

    while getopts 'd:h' argv; do
    case "${argv}" in
        d) local target_dir="${OPTARG}" ;;
        h)
           printf "Usage: remove_file_end_strings [ -d <work directory> ] <string to remove>\n"
           return 1
           ;;
    esac

在这里看起来不错,因为没有自动换行,但是当限制为80个字符时,wordwrapped看起来非常不整洁。 当我想要的是这样的东西,这在python或ruby中很简单:

    while getopts 'd:h' argv; do
    case "${argv}" in
        d) local target_dir="${OPTARG}" ;;
        h)
           printf "Usage: remove_file_end_strings [ -d <work "
                  "directory> ] <string to remove>\n"
           return 1
           ;;
    esac

我的google-fu让我失望了,所以有没有办法在bash中实现这个目标,或者我只是不得不继续坚持一块木头? TA

编辑:我刚刚决定了我的次优解决方案:

    while getopts 'd:h' argv; do
    case "${argv}" in
        d) local target_dir="${OPTARG}" ;;
        h)
            printf "Usage: remove_file_end_strings [ -d <work "
            printf "directory> ] <string to remove>\n"
            return 1
            ;;
    esac
done

2 个答案:

答案 0 :(得分:2)

很容易打破这条线,但是当你缩进下一行时,更难以引入任何额外的空格或标记边界。没有缩进,它很简单但很难看:

{
    printf "Usage: remove_file_end_strings \
[ -d <work directory> ] <string to remove>\n"
}

无论好坏,echo在接受的内容中更为草率:

echo 'This is my string'   \
     'that is broken over' \
     'multiple lines.'

这将3个参数传递给echo而不是1,但由于参数是用空格连接的,所以它的效果相同。

在您的情况下,当您将整个邮件放在格式字符串中时,您可以模拟相同的行为:

printf "%b " 'This is my string'    \
             'that again is broken' \
             'over multiple lines.\n'

虽然当你有一个带有不同插槽的正确格式字符串时,这显然不起作用。

在这种情况下,有黑客攻击:

 printf "I am also split `
        `across %s `
        `lines\\n"  \
        "a number of"

答案 1 :(得分:0)

将内联文档与<<-运算符一起使用:

while getopts 'd:h' argv; do
    case "${argv}" in
            d) local target_dir="${OPTARG}" ;;
            h)
                    cat <<-EOT
                    Usage: remove_file_end_strings [ -d <work directory> ] <string to remove>
                    EOT
    esac
done

请参阅man bash并查找Here Documents

  

如果重定向运算符是&lt;&lt; - ,那么所有前导制表符都是   从输入行和包含分隔符的行中删除。这个   允许此脚本中的文档缩进          一种自然的方式。

如果需要在行中断,请管道sed命令,该命令将删除字符串之间的标签:

while getopts 'd:h' argv; do
    case "${argv}" in
            d) local target_dir="${OPTARG}" ;;
            h)
                    cat <<-EOT | sed 's/\t*\([^\t]*\)/ \1/2g'
                    Usage: remove_file_end_strings [ -d <work \
                    directory> ] <string to remove>
                    EOT
    esac
done