使用 grep 和 for 重命名文件

使用 grep 和 for 重命名文件

我想将具有以下扩展名的文件重命名:.txt、.data、.conf 至“.xml”

你好.txt -> 你好.xml

为此,文件还必须包含以下行:<?xml version="1.0" encoding="UTF-8"?>

这就是我所拥有的:

for file in *
do
if [ $(grep -Rc '<?xml version="1.0" encoding="UTF-8"?>' --include ".txt" --include ".data" --include "*.conf") = true ]
then
rename extension to: .xml
fi
done

有任何想法吗?

答案1

如果你需要这样做grep然后for也许是这样的?

grep -RlZ '<?xml version="1.0" encoding="UTF-8"?>' --include "*.txt" --include "*.data" --include "*.conf" | 
  xargs -0 sh -c 'for f; do echo mv -- "$f" "${f%.*}.xml"; done' sh

echo一旦您确信它正在做正确的事情,请删除)。

  • grep -RlZ输出找到匹配项的文件名称的空分隔列表

  • xargs -0将该空分隔列表传递给sh -c

  • for f将文件名作为位置参数循环

或者(如果允许您使用while而不是for)您可以跳过xargs和附加的 shell scriptlet,例如

grep -RlZ '<?xml version="1.0" encoding="UTF-8"?>' --include "*.txt" --include "*.data" --include "*.conf" | 
  while IFS= read -r -d '' f; do echo mv -- "$f" "${f%.*}.xml"; done

答案2

find . -type f \( -name "*.txt" -o -name "*.data" -o -name "*.conf" \) -exec sh -c '
    for file in "$@"; do
        if grep -qF "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" "$file"; then
            mv -- "$file" "${file%.*}.xml"
        fi
    done
' findshell {} +

我认为find在这种情况下更合适。它递归地查找带有.txt,.data.conf扩展名的常规文件,并检查您提供的字符串是否存在于每个文件中。如果是,那么它将.xml通过命令将扩展名更改为mv

如果您不确定代码是否会按预期工作,您可以在echo前面添加一个mv以查看它的作用。

我还应该提到该脚本不依赖于非 POSIX 实用程序。

答案3

你可以试试这个:

for file in *.{txt,conf}; do 
  [[ $(grep "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" "$file") ]] && \
  mv "$file" "${file%.*}.xml" || echo "$file" " does not match"
done

答案4

使用bash

shopt -s globstar dotglob nullglob extglob

string='<?xml version="1.0" encoding="UTF-8"?>'

for pathname in ./**/*.@(txt|data|conf); do
    if [[ -f $pathname ]] && grep -q -F "$string" "$pathname"; then
        mv -i "$pathname" "${pathname%.*}.xml"
    fi
done

我首先设置一些默认情况下通常不会设置的 shell 选项bash

  • globstar启用**递归匹配子目录的通配模式。
  • dotglob使通配模式与隐藏名称相匹配。
  • nullglob使不匹配的模式完全消失,而不是保持未展开状态。这确保了如果没有匹配,我们的循环稍后将不会运行。
  • extglob启用扩展的通配模式,例如@(txt|data|conf)匹配括号内的字符串之一。

然后,我们循环遍历候选名称并测试每个名称的给定字符串。如果找到该字符串,则通过将最后一个点字符后面的文件名后缀替换为 来重命名该文件xml

相关内容