使用iconv转换CSV编码:目录兼容性及仅筛选文件的方法问询
解决iconv转换CSV编码的脚本问题
咱们一步步来拆解你的问题:
问题1:iconv处理目录会出现什么情况?
iconv是专门用来转换文件内容编码的工具,它完全不支持处理目录。如果你的脚本不小心把目录传给它,它会直接抛出类似这样的错误:
iconv: cannot convert directory 'xxx' to file
不仅不会忽略目录,还会直接中断脚本执行,导致后续的文件都没法处理。
问题2:如何只遍历目录下的文件,避免处理目录?
首先得说:Unix/Linux系统里的文件名根本不允许包含/,所以你担心“名称含/的文件被误过滤”的情况其实不会发生~
至于只筛选文件的可靠方法,绝对不推荐用ls配合管道的方式(比如ls -p | grep -v /)——这种方式在文件名包含空格、换行符等特殊字符时会彻底失效。更稳妥的有两种方案:
方案1:用for循环+文件判断(直观易读)
#!/bin/bash # 定义目标目录 TARGET_DIR="directory/" # 遍历目录下的所有项,引号确保带空格的文件名能被正确识别 for item in "$TARGET_DIR"*; do # 判断当前项是否为普通文件(跳过目录、符号链接等) if [ -f "$item" ]; then # 生成临时文件存储转换结果,避免输入输出同文件的问题 temp_file=$(mktemp) # 执行编码转换 iconv -f "windows-1252" -t "UTF-8" "$item" -o "$temp_file" # 替换原文件(如果想保留原文件,改成 mv "$temp_file" "${item}.utf8" 即可) mv "$temp_file" "$item" fi done
方案2:用find命令(简洁高效)
如果你的目录结构简单,用find可以直接筛选出目标文件,不用额外的判断逻辑:
#!/bin/bash TARGET_DIR="directory/" # -maxdepth 1:只遍历目标目录的直接子项,不深入子目录 # -type f:只匹配普通文件 # -exec:对每个找到的文件执行转换命令 find "$TARGET_DIR" -maxdepth 1 -type f -exec sh -c ' temp_file=$(mktemp) iconv -f "windows-1252" -t "UTF-8" "$1" -o "$temp_file" mv "$temp_file" "$1" ' sh {} \;
顺便提下你原脚本的几个问题
- 变量赋值错误:
FileName=$item应该写成FileName="$item",不加引号的话,带空格的文件名会被拆分成多个变量值; - 输入输出同文件:
iconv ... FileName -o FileName会直接报错,因为iconv不允许输入输出为同一个文件,必须用临时文件中转; - 用
for item in $(ls directory/)遍历文件是反模式:遇到带特殊字符的文件名会直接出错,一定要避免这种写法。
内容的提问来源于stack exchange,提问作者Telvanis
相关产品推荐
相关产品推荐

