有条件地交换一系列文件名

有条件地交换一系列文件名

如果有以下问题:我有一系列成对的文件(但并非总是如此)。有 2400??????_001.jpg 和 2400??????_002.jpg。我需要交换 _001 和 _002。所以我想我可以这样做:

for f in $(find -type f -name "*_002.jpg"); do mv "${f}" "${f%_002.jpg}_003.jpg"; done
for g in $(find -type f -name "*_001.jpg"); do mv "${g}" "${g%_001.jpg}_002.jpg"; done
for h in $(find -type f -name "*_003.jpg"); do mv "${h}" "${h%_003.jpg}_001.jpg"; done

奇怪的是,在第 2 步之后,我得到的 *_003.jpg 和 *_002.jpg 完全相同。这是怎么回事?

然后问题就变得有点困难了:我只希望在对的两个成员都存在的情况下进行交换。有时只有 2400??????_001.jpg 存在,而 2400??????_002.jpg 缺失。如果是这种情况,那么我希望保留 2400??????_001.jpg。

答案1

在 shell 中尝试一下bash

find -type f -name "*_001.jpg" -print0 | while read -d $'\0' f; do
  t=$(mktemp --tmpdir=$(dirname "$f"))
  [ -f "${f%_001.jpg}_002.jpg" ] && \
  mv -v "$f" "$t" && mv -v "${f%_001.jpg}_002.jpg" "$f" && mv -v "$t" "${f%_001.jpg}_002.jpg"
done

作为一个脚本它应该看起来像这样(更易读一些):

#!/bin/bash
find -type f -name "*_001.jpg" -print0 | while read -d $'\0' f; do
  t=$(mktemp --tmpdir=$(dirname "$f"))
  [ -f "${f%_001.jpg}_002.jpg" ] && \
    mv -v "$f" "$t" && \
    mv -v "${f%_001.jpg}_002.jpg" "$f" && \
    mv -v "$t" "${f%_001.jpg}_002.jpg"
done

解释:

  • 首先,我们用 创建一个文件列表find。要处理奇怪的文件名,请使用-print0nullbyte 分隔文件
  • while read -d $'\0' ffind:读取由空字节分隔的输出
  • 创建临时文件
  • 检查两个文件是否存在
  • 将原始文件(001)移至临时文件
  • 将 002 移至 001
  • 将临时文件移动到 002

相关内容