3

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

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

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

任何帮助将不胜感激,我绝不会与此解决方案结婚,因此,如果您能想到一个更优雅的解决方案,但与我的建议不同,我将非常高兴听到它。谢谢

4

4 回答 4

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

于 2013-01-30T20:24:14.117 回答
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 命令一样。

于 2013-01-30T20:42:40.723 回答
0

这是一个可以为您工作的 Perl 示例:

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

没有测试过。;-)

于 2013-01-30T20:59:35.310 回答
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
于 2013-01-30T19:40:46.990 回答