Awk 提取部分列以生成cp命令

Awk 提取部分列以生成cp命令,awk,sed,Awk,Sed,我想创建复制命令,将文件从一个目录复制到它的后面,并删除后缀日期。那里有多个文件 例如文件LOAN.DAILY.20191204 要创建命令吗 cp LOAN.DAILY.20191204 ../LOAN.DAILY 我的尝试 ls -lrt | awk ' /DAILY/{ print "cp " , $9 , "../" , sub(/\.20191204$/,""); $9 }' 获取输出 cp LOAN.DAILY.20191204 ../ 1 为什么会出现此1,根据: 如前所述

我想创建复制命令,将文件从一个目录复制到它的后面,并删除后缀日期。那里有多个文件

例如文件
LOAN.DAILY.20191204

要创建命令吗

cp LOAN.DAILY.20191204 ../LOAN.DAILY
我的尝试

ls -lrt | awk ' /DAILY/{ print "cp " , $9 , "../" , sub(/\.20191204$/,""); $9 }'
获取输出

cp  LOAN.DAILY.20191204 ../ 1
为什么会出现此1,根据:

如前所述,sub()的第三个参数必须是变量、字段或数组元素。awk的某些版本允许第三个参数是不是左值的表达式。在这种情况下,sub()仍然搜索模式并返回零或一,但是替换的结果(如果有的话)会被丢弃,因为没有地方放置它

这解释了为什么输出中会出现
1

如果要修改第九列的值,需要在
sub
调用中指定它:

ls -lrt | awk ' /DAILY/{ orig=$9; sub(/\.20191204$/,"", $9); print "cp " , orig , "../", $9 }'
在此命令中,
$9
的原始值存储在变量
orig
中,然后使用
sub
删除日期后缀,最后使用新旧值构造
cp
命令。

一种简单的方法:

shopt -s nullglob
for file in *.DAILY.* ; do cp "$file" ../"${file%.*}";  done
:避免任何不必要的副本,以防glob无法获得匹配

:Shell的参数扩展,用于从字符串的末尾到第一个匹配的
反向剥离所有内容

我想不起更好、更短的方法来实现这一点,尽管我认为有很多。

这可能适合您(GNU-sed):

检查输出后,使用此版本执行副本

ls *DAILY* |  sed -E 's#^(.*)\..*#cp & \1#e'
或使用GNU并行的替代方案:

parallel --dry-run cp {} {.} ::: *DAILY*
再次检查结果,如果都正常,则使用:

parallel cp {} {.} ::: *DAILY*

这是正确的做法。如果没有
nullglob
设置,您可以为*20191204中的文件执行:
;执行[[-f“${file}]”和&cp“${file}”。/“${file%20191204}”;完成
。与上面的不同之处在于测试
$file
是否为实际文件(修复nullglob),并且我还明确定义了日期。您可能有兴趣查看允许复制的mass move and rename命令。
parallel cp {} {.} ::: *DAILY*