我有一个类似"M;12345678900000;Z;;FEWO;F;010622;0.0;;;1.00;0.00;1.25;Y;;;XXX"的字符串,其中第七个字段是ddmmyy格式的日期.我需要用相同格式的日期替换此字段,但要提前3天.

我try 了以下几种方法:

echo "M;12345678900000;Z;;FEWO;F;010622;0.0;;;1.00;0.00;1.25;Y;;;XXX" | sed "s/;\([0-3][0-9][0-1][0-9]2[0-9]\);/;$(date -d "$(date -d \1 '+%d%m%y') - 3 days" '+%d%m%y');/"

问题是,我可以使用引用(\1)或脚本($(date..)),但我不能创建两者都工作的工作示例.我认为这是引语的问题,但我也无法正确地避开它们.同样,Sed的switch ,比如-E, -e, -r,也帮不了我.我希望看到一个有效的sed示例,但我也在考虑用awk来解决这个问题.

如果有任何帮助,我很感激.

推荐答案

awk可能是更好的候选者,但当你要求sed解决方案时…

使用GNU sed,您可以使用shell 执行成功替换的结果,并使用结果替换模式空间,这要归功于替换命令的e标志.使用GNU coreutils if your line does not contain 102 formatting controls and no quotes中的date实用程序的示例:

$ printf 'M;12345678900000;Z;;FEWO;F;010622;0.0;;;1.00;0.00;1.25;Y;;;XXX' |
sed -E 's/(([^;]*;){6})(..)(..)(..)(.*)/date -d "\5\4\3 -3 days" +"\1%d%m%y\6"/e'
M;12345678900000;Z;;FEWO;F;290522;0.0;;;1.00;0.00;1.25;Y;;;XXX

这将用生成预期输出的date命令替换输入行.以您的示例为例:

date -d "220601 -3 days" +"M;12345678900000;Z;;FEWO;F;%d%m%y;0.0;;;1.00;0.00;1.25;Y;;;XXX"

注意从日-月-年到年-月-日的重新排序.然后它由shell 执行,这要归功于e标志.

如果该行的其余部分可以被解释为date的格式化命令,我们需要一些更复杂的东西:

$ printf 'M;12345678900000;Z;;FEWO;F;010622;0.0;;;1.00;0.00;1.25;Y;;;XXX' |
sed -E 'h
s/([^;]*;){6}(..)(..)(..).*/date -d "\4\3\2 -3 days" +%d%m%y/e
G;s/(.*)\n(([^;]*;){6}).{6}(.*)/\2\1\4/'
M;12345678900000;Z;;FEWO;F;290522;0.0;;;1.00;0.00;1.25;Y;;;XXX
  • 将包含输入行的图案空间复制到保持空间(h).

  • 将整行替换为date -d "yymmdd -3 days" +%d%m%y,其中yymmdd是年-月-日格式的日期(在您的示例中为220601).结果由shell 执行,模式空间被替换为结果,这要归功于e标志.在您的示例中,它现在包含290522.

  • 将换行符和保留空格附加到模式空格(G).在这一点上,模式空间包含(使用您的示例):

    290522\nM;12345678900000;Z;;FEWO;F;010622;0.0;;;1.00;0.00;1.25;Y;;;XXX
    
  • 最后,用您想要的最终格式替换模式空间.

Linux相关问答推荐

Linux x86_64上PIE ELF可执行文件的.Text段的基本虚拟地址

无法在嵌入式 Linux 中使用 libjpeg 以 RGB888 在 LCD(黑色)上显示 JPEG

awk内部的变量操作

在 linux 中插入带有 sed 命令的文件的行

如何在 Linux 上使用 -grep 构建过滤间隔的命令

如果 bash 中已经存在文件名,则创建新文件但添加数字

tmux:挂起不加载,不响应任何选项命令

在 Bash 中识别接收到的信号名称

模拟器在内核映像文件中找不到Linux 版本字符串

有没有办法在整个项目代码中的某个日期之后找出更改的文件?

低功耗蓝牙:在 linux 中监听通知/指示

如何 grep 精确的文字字符串(无正则表达式)

NGINX:connect() 到 unix:/var/run/php7.0-fpm.sock 失败(2:没有这样的文件或目录)

从linux命令行写入串口

docker images显示图像,docker rmi表示没有这样的图像或参考不存在

bash 脚本中的自动 docker 登录

比较linux中两个未排序的列表,列出第二个文件中的唯一性

将原始数据发送到 TCP 服务器的 Linux 工具

给定一个 linux 用户名和密码,我如何测试它是否是有效帐户?

我可以告诉 Linux 不要换出特定进程的内存吗?