使用sed将首字母转换为小写

时间:2018-09-10 11:05:50

标签: bash sed

我正在运行安装了bash的基于Docker Alpine的映像。

bash --version
GNU bash, version 4.3.48(1)-release (x86_64-alpine-linux-musl)

在以下命令中,我正在尝试将月份的第一个字母转换为小写字母,但它不起作用:

find ../ -type f -name "*.md" \
        -exec bash -c '
            f=${1#./}
            gzip -9 "$f"
            mv "$f".gz "$f"
            aws s3 cp "$f" s3://bucket_name/ --metadata time=$(date +%d-%b-%Y.%H%M | sed '\''s#\([A-Z]\)#\L\1#'\'') ' _ {} \;

它分配给文件的date属性是:

"Metadata": {
    "timestamp": "10-LSep-2018.1054"
}

\L在这种情况下不起作用。预计日期应该是"10-sep-2018.1054"

我如何使其与Docker映像中存在的bash版本一起使用?

5 个答案:

答案 0 :(得分:1)

可以仅显示受影响的部分来简化问题:

date +%d-%b-%Y.%H%M | sed '\''s#\([A-Z]\)#L\1#'\''

首先让我“清理”它:

date +%d-%b-%Y.%H%M | sed 's#\([A-Z]\)#L\1#'

我在这里看到的是您使用L作为文字字母,而不是命令。您需要这样转义(\ L):

date +%d-%b-%Y.%H%M | sed 's#\([A-Z]\)#\L\1#'

您可以测试它是否执行:

:~# docker container run --rm alpine /bin/sh
/ # date +%d-%b-%Y.%H%M | sed 's#\([A-Z]\)#\L\1#'
10-LSep-2018.1510

答案 1 :(得分:1)

GNU sed应该这样做:

$ date +'%d-%b-%Y.%H%M' | sed 's/-./\L&/'
10-sep-2018.1332

要在bash -c '...'中正确转义它:

bash -c '... time="$(date +"%d-%b-%Y.%H%M" | sed "s/-./\L&/")" ...'

如果没有可用的GNU sed\L扩展名是必需的),只需将日期保存到变量中并使用parameter expansion

$ d=$(date +'%d-%b-%Y.%H%M')
$ echo "${d,,}"
10-sep-2018.1337

答案 2 :(得分:1)

事实证明,OP仅能访问不能识别\ L替换命令的最低版本sed,并且对于他的用例来说,可以将输出中的所有字母都大写。

最简单的方法是使用命令

tr [:upper:] [:lower:]

尽管如此,当然还有其他可行的选择,例如@PesaThe建议的“纯bash”解决方案,或者使用Andrea Giammarchi建议的sed“ y”转换命令(如果有的话)(尽管我会争论)则另外两个选项是更可取的,因为它们应用了更适合该任务的工具。

如果仅输出的第一个大写字母可以被转换并且sed \ L替换命令不可用,我建议您使用功能更强大的脚本或编程语言,其中的任务应微不足道。解决。在“纯重打击”中也必须有这种可能,但是我可以凭空提出的方法似乎异常复杂。

为说明起见,这是一个最小的C程序,可以在适当的编码情况下完成该任务:

#include <stdio.h>
main() {
    int c;
    while ((c = getchar()) != EOF) {
        if (c >= 'A' && c <= 'Z') {
            putchar(c + 'a' - 'A');
            break;
        }
        putchar(c);
    }
    while ((c = getchar()) != EOF) putchar(c);
}

答案 3 :(得分:0)

few variants of a possible answer in this other thread,但似乎最能满足您需求并且也是最容易阅读的一个是:

sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'

这应该在包括macOS在内的几乎所有地方都有效。

答案 4 :(得分:0)

这可能对您有用(GNU sed):

sed 's/$/:JjFfMmAaSsOoNnDd/;s/\([JFMASOND]\)\(.*\):.*\1\(.\).*/\3\2/' file

这将大写字母J,F,M,A,S,O,N或D替换为小写字母。