我正在运行安装了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版本一起使用?
答案 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替换为小写字母。