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*