将字符插入文件名

时间:2013-01-30 19:16:56

标签: regex unix grep

我有一个目录,其中包含一堆标题为(例如)

的文件
how it is:            how it should be:
945TITLE-1.txt        945TITLE-00.txt
945TITLE-10.txt       945TITLE-01.txt
945TITLE-2.txt        945TITLE-02.txt
945TITLE-23.txt       945TITLE-03.txt
945TITLE-3.txt        945TITLE-10.txt
945TITLE.txt          945TITLE-23.txt

执行短划线字符的数字和文本可以更改,因此需要变量。 忽略未编号的文件(在此实例中为945TITLE.txt) 我正在使用以下行来获取所有以短划线和单个数字结尾的文件

file=`ls -1 working/pages/files | grep [-][0-9].txt`

但现在我无法弄清楚如何在短划线和数字之间拼接0。

for file in $filelist
do  
????
done

经过几次尝试后,我对此最为兴奋:

for file in working/pages/files/$filelist
do  
f1=${filelist%%[-]*}
f2=${filelist##*[-]}
finalName=${f1}-0${f2}
echo $finalName
mv $file working/pages/files/$finalName
done

$finalName的输出每次都是945TITLE-03.txt,它只会将mv命令应用于945TITLE-1.txt(错误地将其更改为945TITLE-03.txt)并说明它找不到其他文件(因为它只查看第一个文件的working/pages/files/文件夹)

任何帮助都会非常感激,我绝不会嫁给这个解决方案,所以如果你能想到一个比我提议的更优雅的那个,我会非常乐意听到它。谢谢

4 个答案:

答案 0 :(得分:0)

这是我在这里根据您的开始制作的一个简单示例。有一些有趣的特殊外壳可以处理你的945TITLE.txt案例:

#!/bin/bash

for file in 945*
do
    suffix=${file##*[.]}
    base=$(basename ${file} .${suffix})
    prefix=${base%%[-]*}
    number=${base##*[-]}
    case ${number} in
        ''|*[!0-9]*) number=0 ;;
    esac
    echo ${prefix}-$(printf "%02d" ${number}).${suffix}
done

答案 1 :(得分:0)

想法:

  1. 逐行处理(示例945TITLE-1.txt)
  2. 首先用“ - ”分隔(给出“945TITLE”&“1.txt”,)
  3. 然后将第一个拆分的第二个输出拆分为“。” (给出“1”&“txt”)

    ls -1 | awk '{ 
             n=split($0, array , "-");
             if( n > 1 ) {
               printf("%s-",array[1]);
               split(array[2],arraydot,".");
               printf("%02d.%s\n", arraydot[1], arraydot[2]);
              } else {
               split(array[1],arraydot, "."); 
               printf("%s-00.%s\n",arraydot[1],arraydot[2]);
             }
          }' | sort
    

    上述其他条件处理945TITLE.txt

  4. 的大小写

答案 2 :(得分:0)

这个awk-onliner可以工作:(你可以先删除结尾|sh来检查生成的mv命令。)

ls -[your options] |awk  -F'-|\\.' 'NF<3{x=$0;sub(/\./,"-00.",x)}NF>2{x=sprintf ("%s-%02d.%s",$1,$2,$3)}{print "mv "$0" "x}' |sh

我用文本文件模拟它。

kent$  cat test.txt
945TITLE-1.txt
945TITLE-10.txt
945TITLE-2.txt
945TITLE-23.txt
945TITLE-3.txt
945TITLE.txt

kent$  awk  -F'-|\\.' 'NF<3{x=$0;sub(/\./,"-00.",x)}NF>2{x=sprintf ("%s-%02d.%s",$1,$2,$3)}{print "mv "$0" "x}' test.txt
mv 945TITLE-1.txt 945TITLE-01.txt
mv 945TITLE-10.txt 945TITLE-10.txt
mv 945TITLE-2.txt 945TITLE-02.txt
mv 945TITLE-23.txt 945TITLE-23.txt
mv 945TITLE-3.txt 945TITLE-03.txt
mv 945TITLE.txt 945TITLE-00.txt

如果将结果传递给sh,就像awk.....|sh那样执行mv命令。

答案 3 :(得分:0)

这是一个可能适合您的Perl示例:

perl -E 'while(<*.txt>){ $a = $_; s/-\K\d\./0$&/ || s/\D\K\./-00./; rename $a, $_; }'

没有经过测试。 ; - )