【问题标题】:Alternative for AWK useAWK 使用的替代方案
【发布时间】:2020-07-15 12:55:44
【问题描述】:

我希望有一个更优雅的文件批量重命名解决方案,如下所示。文件格式为DEV_XYZ_TIMESTAMP.dat,我们需要它们为T-XYZ-TIMESTAMP.dat。 最后,我将它们全部(在同一侧)复制到renamed 文件夹中:

ls -l *dat|awk '{system("cp " $10 " renamed/T-" substr($10, index($10, "_")+1))}'

所以,首先我列出了所有 dat 文件,然后选择第 10 列(文件名)并使用 awk 的 system 函数执行命令。 该命令本质上是将原始文件名复制到具有新文件名的 renamed 文件夹中。 通过在(包括)_ 之前删除 (awk substring function) 前缀并添加“T-”前缀来创建新文件名。

有效地:

cp DEV_file.dat renamed/T-file.dat

有没有办法将cpmv 与一些正则表达式规则一起使用,以更优雅的方式实现同​​样的效果?

谢谢

【问题讨论】:

  • Awk 是一种用于处理文本的工具。 Shell 是一种用于操作文件/进程和对工具的调用排序的工具。您正在尝试使用 awk 来操作(重命名)文件,因此您使用了错误的工具 - 只需使用 shell。

标签: linux bash shell awk mv


【解决方案1】:

如果你有rename 实用程序

rename -E "s/[^_]*/T/" -e "s/_/-/g" *dat

演示

$ls -1
ABC_DEF_TIMESTAMP.dat
DEV_XYZ_TIMESTAMP.dat
$rename -E  "s/[^_]*/T/" -e "s/_/-/g" * 
$ls -1
T-DEF-TIMESTAMP.dat
T-XYZ-TIMESTAMP.dat
$

【讨论】:

【解决方案2】:

我会这样做:

cpdir=renamed
for file in *dat; do
    newfile=$(echo "$file" | sed -e "s/[^_]*/T/" -e "y/_/-/")
    cp "$file" "$cpdir/$newfile"
done

sed 脚本将每个非下划线前导字符转换为单个 T,然后将每个 _ 替换为 -。如果cpdir在执行前不确定是否存在,你可以在第一行之后简单地添加mkdir "$cpdir"

【讨论】:

    【解决方案3】:

    你可以使用这个脚本:

    for file in *.dat; do
       f="${file//_/-}"
       mv "$file" renamed/T-"${f#*-}"
    done
    

    You must avoid parsing output of ls command.

    【讨论】:

    • 是的,但请务必在第一行添加#!/bin/bash shebang,因为如果sh 得到脚本,它会抱怨。
    • @Quasímodo:问题也被标记为bash
    • @hummingBird: f="${file//_/-}"- 替换$file 中的所有_,并将结果存储在变量f 中。 "${f#*-}" 删除测试,直到 - 中的第一个 $f
    • @anubhava 当然,这是一个完全有效的答案,这只是对 OP 的提醒。
    • 只是为了让您知道我已在接受答案前 6 分钟发布了我的答案。同样在效率方面,如果某些事情可以完全在 bash 本身中完成,那么避免产生子进程和调用外部实用程序总是更快。 Quasimodo 的 fork 2 个子进程:一个用于命令替换,两个用于$9...) 内部的管道。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-13
    • 2015-03-03
    相关资源
    最近更新 更多