如何在 sed 或 awk 中搜索一个点和一个数字,并在数字前加上前导零?

How can I search for a dot an a number in sed or awk and prefix the number with a leading zero?

我正在尝试修改大量文件的名称,所有文件都具有以下结构:

4.A.1 Introduction to foo.txt
2.C.3 Lectures on bar.pdf
3.D.6 Processes on baz.mp4
5.A.8 History of foo.txt

我想在最后一位数字前加一个零:

4.A.01 Introduction to foo.txt
2.C.03 Lectures on bar.pdf
3.D.06 Processes on baz.mp4
5.A.08 History of foo.txt

起初我试图通过 sed(FreeBSD 实现)获取新名称:

ls | sed 's/\.[0-9]/0&/'

但是我在 .

之前得到了零

注意:替换第二个点也可以。我也开放使用 awk.

这条管道应该适合你:

ls | sed 's/\.\([0-9]\)/.0/'

此处的sed命令将捕获数字并将其替换为前面的0

此处, 引用第一个(并且仅在本例中)捕获组 - 带括号的表达式。

虽然它在这里可能对你有用,但一般来说 slicing and dicing ls output is fragile, whether using sed or awk or anything else. Fortunately one can accomplish this robustly in plain old POSIX sh using globbing and fancy-pants parameter expansions:

for f in [[:digit:]].[[:alpha:]].[[:digit:]]\ ?*; do
    # $f = "[[:digit:]].[[:alpha:]].[[:digit:]] ?*" if no files match.
    if [ "$f" != '[[:digit:]].[[:alpha:]].[[:digit:]] ?*' ]; then
        tail=${f#*.*.}              # filename sans "1.A." prefix
        head=${f%"$tail"}           # the "1.A." prefix
        mv "$f" "${head}0${tail}"
    fi
done

(编辑:过滤掉与所需格式不匹配的文件名。)

如果它对其他人有帮助,可以替代@costaparas 回答:

ls | sed -E -e 's/^([0-9][.][A-Z][.])//' > files

然后创建脚本文件:

cat files | awk '{printf "mv \"%s\" \"%s\"\n", [=11=], [=11=]}' | sed 's/\.0/\./' > movefiles.sh

我也开放使用awk

file.txt内容为:

4.A.1 Introduction to foo.txt
2.C.3 Lectures on bar.pdf
3.D.6 Processes on baz.mp4
5.A.8 History of foo.txt

然后

awk 'BEGIN{FS=OFS="."}{="0" ;print}' file.txt

产出

4.A.01 Introduction to foo.txt
2.C.03 Lectures on bar.pdf
3.D.06 Processes on baz.mp4
5.A.08 History of foo.txt

说明:我将点 (.) 设置为字段分隔符和输出字段分隔符,然后对于每一行,我通过连接 0 和所述列将前导 0 添加到第三列 (</code>) .终于我<code>print这样改线了

(在 GNU Awk 5.0.1 中测试)

这可能对你有用 (GNU sed):

sed 's/^\S*\./&0/' file

这将在每行的第一个非空字符字符串的最后一个 . 之后附加 0