批量使用字符串重命名多个文件并允许重复

时间:2017-09-28 20:42:40

标签: bash

我正在尝试获取单个文件prt-dealrpt,将其拆分为多个文件,根据文件中的特定字符串重命名文件,并允许与(1),(2)等重复文件文件名的结尾。

以下是文件的一部分:

Vendor: GREAT LAKES                 Buyer - Melissa         APU/DND
        Begin Date:  10/16/2017 
        End Date:    12/08/2017

Vendor: SENECA                      Buyer - Bill            This is a note
        Begin Date:  10/16/2017
        End Date:    12/08/2017

Vendor: MC-CAIN                     Buyer - Bill            APU/DND
        Begin Date:  10/16/2017
        End Date:    12/08/2017

Vendor: MC-CAIN                     Buyer - Ethan           APU\DND
        Begin Date:  10/16/2017
        End Date:    12/08/2017

编辑:上面的文件在同一行上有更多关注供应商名称。大多数文件不会重命名,因为它正在寻找AUP / DND目录。重命名的实际上是重命名为行的最后一部分,因此在此示例中,供应商SENECA的新名称将为This is a note.dat

我需要在每次使用单词Vendor时拆分文件 我使用名为split.sh

的shell成功完成了此操作
csplit --prefix page --suffix-format %02d.dat prt-dealrpt '/^Vendor/' '{*}'

这会创建名为page00.dat page001.dat page02.dat的文件,依此类推。

接下来,我尝试将文件重命名为供应商名称。我正在使用名为fixname.bat

的批处理文件执行此操作
@echo off

for %%i in ("C:\Users\waker\Documents\Unipro\Vendor\*.dat") do (
  for /f "tokens=2 delims=:" %%j in ('findstr /B "Vendor" "%%i"') do (
    ren "%%i" "%%j.temp_dat"
  )
)

ren *.temp_dat *.dat

但这不起作用,但它不允许重复。它将跳过将创建重复名称的文件。使用上面的示例,我将留下GREAT LAKES.dat SENECA.dat MC-CAIN.datpage03.dat。我希望将副本命名为MC-CAIN(2).dat

如果有人建议使用一个按钮而不是运行两个单独的命令,那么任何帮助都会受到赞赏。

我正在运行Windows 10,安装了“在Windows上安装Bash on Ubuntu”。

1 个答案:

答案 0 :(得分:0)

我会将以下内容放入bash脚本中,并在包含页面* .dat文件的目录中执行:

int* ptrA = nullptr;
std::cout<<ptrA<<"\n"; // print 0
char* ptrB = nullptr;
std::cout<<ptrB<<"\n"; // print nothing, program exit with code 0
... // never execute

我认为Windows bash附带了Linux中可用的标准gnu工具,例如:grep,sort,tail和sed。

当我在Linux机器上运行它时,我使用script.sh中的上述代码获得了以下结果:

newext="temp_dat"
for i in page*.dat;
do
        filename=$(grep 'Vendor' $i|sed 's/^.*Vendor:\ *\(..*\) *Buyer.*/\1/;s/\ *$//');
        if [[ $filename == '' ]]; then
                echo "Skipping file $i with no Vendor"
                continue;
        fi
        dstfile="${filename}.${newext}"
        if [[ -e "$dstfile" ]]; then
                dstfile="${filename} (1).${newext}";
                if [[ -e "$dstfile" ]]; then
                        lastfilenum=$(ls -1 "${filename} ("*").${newext}"|sort|tail -1|sed "s/^.* (\(.*\)).*/\1/")
                        nextfilenum=$(expr $lastfilenum + 1)
                        dstfile="${filename} (${nextfilenum}).${newext}"
                fi
        fi;
        mv "$i" "$dstfile"
done