修剪文件名的子字符串,每个子字符串将模式匹配到给定长度

修剪文件名的子字符串,每个子字符串将模式匹配到给定长度

在下面的示例中,模式由 分隔-,长度为 3。我的问题是:是否有更有效的方法来做到这一点?

$ echo $foo
./abcd-123-efghij-45678.pdf
$ echo "$foo" | sed -E 's:([^-\.\/]{3})([^-]*):\1:g'| sed "s/$/.${foo##*.}/"
./abc-123-efg-456.pdf
$ foo=${foo%.pdf}.djvu
$ echo $foo
./abcd-123-efghij-45678.djvu
$ echo "$foo" | sed -E 's:([^-\.\/]{3})([^-]*):\1:g'| sed "s/$/.${foo##*.}/"
./abc-123-efg-456.djvu

...我最终需要这个命令的目的是在里面替换它for f in $(find . -name pattern); do mv $f $(...);done

答案1

你可以将其缩短为

echo ./abcd-123-efghij-45678.pdf | sed -E 's:([^-\.\/]{3})([^-]*):\1:g; s/$/.djvu/'

但除此之外,这几乎是你能做的最好的事情了sed

答案2

我想这会对你有帮助,例如你想搜索所有*.txt文件

for f in $(find . -type f -name "*.txt"); 
 do 
    echo mv "$f" $(echo "$f" | sed -E 's:([^-\.\/]{3})([^-]*):\1:g;s/$/.'"${f##*.}"'/')
done

如果您对结果满意,请删除echo并再次运行代码。

答案3

这是一个简单的perl脚本。我非常怀疑它在 CPU 使用或内存消耗方面是否更“高效”,sed但你极不可能注意到运行时的任何差异,并且它更容易阅读、修改和使用:

#! /usr/bin/perl

use strict;
use warnings;

# default to substring lengths of 3
my $maxlen=3;
if ($ARGV[0] =~ m/^\d+$/) {  # if first arg contains only digits
  $maxlen = shift;
};

while(<>) {
  chomp;
  s/#.*|^\s*|\s*$//g;  # strip '#' comments, leading & trailng spaces
  next if (m/^$/);     # skip blank lines

  my ($path,$ext) = '';
  my $filename = $_;

  # extract path (if any)
  if (m/^(.*\/)(.*)/o) {
    ($path,$filename) = ($1,$2)
  };

  # extract filename extension (if any)
  if ($filename =~ m/(^.*)(\..*)$/) {
    ($filename,$ext) = ($1,$2);
  };

  # split into fields on '-', reduce each field to $maxlen.
  my @fields=split /-/,$filename;
  @fields = map { substr($_,0,$maxlen-1) } @fields;

  print "$path" . join('-',@fields) . $ext . "\n";
}

使用描述性文件名保存脚本,并使其可执行chmod +x scriptname。我刚刚用了你的 U&L 名字。

输入:

==> erwann1.txt <==
abcd-123-efghij-45678.pdf
./abcd-123-efghij-45678.djvu

==> erwann2.txt <==
gtr-tomwaits-callfromistanbul-chord-ehaugen.mp4 
gtr-tomwaits-callfromistanbul-mribot.mp4 

输出:

$ ./erwann.pl 3 erwann1.txt 
abc-123-efg-456.pdf
./abc-123-efg-456.djvu

$ ./erwann.pl 6 erwann2.txt 
gtr-tomwai-callfr-chord-ehauge.mp4 
gtr-tomwai-callfr-mribot.mp4 

您可以将其运行为:

ls -1 *.mp4 | ./erwann.pl 6
find . -type f -name '*.pdf' | ./erwann.pl 

该脚本将处理包含除换行符之外的任何字符的文件名。如果文件名中可能包含换行符,则可以轻松修改脚本以支持 NUL 终止的输入记录(也许使用Getopt::StdGetopt::Long来处理命令行选项)

相关内容