在ssh中递归地从文件中删除前缀

时间:2020-05-05 22:15:01

标签: linux unix

我有很多图片文件夹(很多!),有些缩略图带有'tn'前缀,而另一些则没有,所以为了能够为所有人编写图库,我尝试从整个目录中递归删除文件的开头删除“ tn”。

因此,有问题的缩略图将包含以下文件:

tngal001-001.jpg
tngal001-002.jpg
tngal001-003.jpg

等...

我需要他们成为:

gal001-001.jpg
gal001-002.jpg
gal001-003.jpg

或更妙的是...如果我能拿走整个tngal001-,那真是太神奇了,因此,在目录gallery中,我有:

gal001/thumbnails/tngal001-001.jpg
gal001/thumbnails/tngal001-002.jpg
gal001/thumbnails/tngal001-003.jpg 
etc...

gal002/thumbnails/tngal002-001.jpg
gal002/thumbnails/tngal002-002.jpg
gal002/thumbnails/tngal002-003.jpg 
etc...

gal003/thumbnails/tngal003-001.jpg
gal003/thumbnails/tngal003-002.jpg
gal003/thumbnails/tngal003-003.jpg 
etc...

,我希望拥有:

gal001/thumbnails/001.jpg
gal001/thumbnails/002.jpg
gal001/thumbnails/003.jpg 
etc...

gal002/thumbnails/001.jpg
gal002/thumbnails/002.jpg
gal002/thumbnails/003.jpg 
etc...

gal003/thumbnails/001.jpg
gal003/thumbnails/002.jpg
gal003/thumbnails/003.jpg 
etc...

我尝试过find . -type f -name "tn*" -exec sh -c 'for f; do mv "$f" "{f#tn}"; done' find sh {} +

find . -type f -exec sh -c 'for file in tn*; do mv "$file" "${file#tn}"; done' findsh {} +

但是我不太正确。我只是想了解如何递归删除字母/重命名,因为我只是想弄清楚这些东西。我发现的所有其他问题似乎都是在谈论从文件名中删除字符,而所有的ASCII字符和转义空格等使我感到困惑。如果有人能用普通英语解释它,我将不胜感激。我并不傻,但是我是linux的新手!我知道一旦了解发生了一切就合乎逻辑。

Kirsty,谢谢您,

2 个答案:

答案 0 :(得分:0)

find . -type f -name "tn*" -exec sh -c '
  for f; do
    fname=${f##*/}
    mv -i -- "$f" "${f%/*}/${fname#tn*-}"
  done
' sh {} +

在开始从文件名中删除前缀之前,需要将"$f"拆分为父路径和文件名。而且您忘记在参数扩展($)中添加${f#tn}

  • ${f##*/}删除最长的前缀*/并保留文件名,例如

    gal001/thumbnails/tngal001-001.jpg -> tngal001-001.jpg
    

    (与basename "$f"相同的结果)

  • ${f%/*}删除最短的后缀/*并留下父路径,例如

    gal001/thumbnails/tngal001-001.jpg -> gal001/thumbnails
    

    (与dirname "$f"相同的结果)

  • ${fname#tn*-}从文件名中删除最短前缀tn*-,例如

    tngal001-001.jpg -> 001.jpg
    

我添加了-i选项,以提示覆盖现有文件。

答案 1 :(得分:0)

您可以遍历gallery中的所有文件夹和文件,然后按以下方式重命名它们。

假设您的文件夹结构为

gallery/
gallery/gal001
gallery/gal002
gallery/gal003
...
gallery/gal001/thumbnails/
gallery/gal002/thumbnails/
gallery/gal003/thumbnails/
...
gallery/gal001/thumbnails/tngal001-001.jpg
gallery/gal001/thumbnails/tngal001-002.jpg
gallery/gal001/thumbnails/tngal001-002.jpg

使用gallery移至cd gallery,然后运行以下代码

for j in *;
 do
    cd $j/thumbnails; 
    for i in  *; 
     do 
       echo "Renaming $j/thumbnails/$i --> $(echo $i|sed "s/tn$j-//1")";
       mv -i $i $(echo $i|sed "s/tn$j-//1"); 
     done
    cd ../..; 
done

说明

for j in *;

循环访问gallery中的所有文件夹,即j包含gal001, gal002, gal003, etc.

cd $j/thumbnails; 

在“ gal001 / thumbnails”目录中移动。

for i in  *; do 

循环访问目录gal001/thumbnails中的所有文件,并且文件名包含在i中。

echo "Renaming $j/thumbnails/$i --> $(echo $i|sed "s/tn$j-//1")"

打印文件名并将其重命名为。 (如果您不想冗长,请将其删除)。

mv $i $(echo $i|sed "s/tn$j-//1"); done

mv -i $i newname重命名$i(循环中当前文件的值)。 -i标志用于提示重命名后的文件名是否已经存在。

sed是流编辑器,通过管道 filename进入sed来获取$i

"s/previous/new/1"用流中的previous值替换new值的首次出现。此处,将tn + j(即目录gal001的值)tngal001-的值替换为“空字符串”(//之间没有任何值)。 / p>

cd ../..返回到gallery