使用每个文件中的文本重命名大量文件的脚本进行重命名

使用每个文件中的文本重命名大量文件的脚本进行重命名

我正在尝试设计一个解决方案来重命名大量文件,以便每个文件的第 3 行中的文本是新文件名。这些文件都具有相同的结构。

这些是 HTML 文件,具体而言,每个文件的第 3 行如下所示。

<TITLE>DATA POPULATION 'CODE on group 1234 by THING'</TITLE>

我想获取单引号之间的所有内容,并使用该文本以该文本作为文件名来重命名该文件。

一次重命名这些会很有用。

答案1

for src in *.html; do
  { read -r x && read -r x && IFS="'" read -r x dst x; } < "$src" &&
     mv -i -- "$src" "$dst.html"
done

(这-i是为了交互的如果两个文件最终具有相同的目标名称,则使用户有机会避免丢失文件)。

答案2

$ awk -v FS="'" -v OFS="\t" 'FNR==3 && NF>2 {print FILENAME, $2; nextfile}' *.txt |parallel --colsep "\t" 'mv {1} {2}'

awk迭代该位置中的所有文件。我们将 定义'为字段分隔符。每当它到达第三行并且有超过 2 个字段(如果我们有两个字段就应该是)时,它会打印出文件名和由制表符分隔的'第二个字段(前两个字段之间的部分)。'然后它跳到下一个文件。

结果通过管道传输到parallel.通过将和替换为结果列中给出的值来parallel执行命令。mv{1}{2}awk

一些注意事项:

  • nextfile并非所有awk版本都可用
  • 文件名中的空格从来都不是一个好主意。如果您awk像这样更改命令,则可以用下划线替换它们:

    awk -v FS="'" -v OFS="\t" 'FNR==3 && NF>2 { gsub(" ", "_", $2); print FILENAME, $2; nextfile}' *.txt

  • 您应该将新文件名移动或复制到另一个文件夹。我不确定awk如果新文件在运行时出现在同一文件夹中会如何反应。

答案3

for j in ./*.txt
do
i=$( sed -n '3p' "$j" | cut -d "'" -f2)
mv "$j" "$i"
done

它将搜索当前目录中的所有文件,并将该文件移动到新目录。

答案4

我会在 Perl 中做这样的事情,而不是把一些缓慢而脆弱的子 shell 放在一起:

perl -e 'while(<>){
  sub no_rename { print "rename @_\n" }
  next unless $. == 3;
  if(my ($f) = /DATA POPULATION +'\''(.*?)'\''/){
      $f =~ s/[^\w]/_/g;
      no_rename $ARGV, $f or warn "rename $ARGV, $f: $!\n";
  }
  close ARGV
}' files ...

您必须更改no_renamerename使其真正执行,而不是显示它。

抱歉,丑了'\'';如果你把它放在一个脚本文件而不是一行中,那应该很简单:

/DATA POPULATION +'(.*?)'/

如果您确实想创建带有空格的文件名,还可以在表达式\s后面添加一个(对于文件名中可能出现的其他字符也类似 - 默认情况下,脚本将用下划线替换除字母和数字之外的所有内容)。\ws///g

相关内容