批量小写的文本文件内容

时间:2012-02-19 18:37:41

标签: bash unicode utf-16 lowercase

半小时后寻找答案,我想不出办法(没有它涉及单独打开每个文本文件,选择全部然后用gedit小写。我想成为能够运行脚本,无论是通过命令行还是最好包含在nautilus脚本中,这样如果我在GUI上选择文件并右键单击脚本和小写,它就会完成。  我知道tr能够知道如何做,但我无法弄清楚如何将以下调用转为tr '[:upper:]' '[:lower:]' < input.txt > output.txt通常,我会将input.txt更改为* .txt和* .txt output.txt,但它不起作用。有什么想法吗?

额外:一旦解决了,如何使其适应nautilus脚本? :

谢谢!

3 个答案:

答案 0 :(得分:2)

修改 结果证明这是一个编码问题 - OP的输入文件是UTF16。

在评论中进行讨论后,OP会将使用less查看的数据复制/粘贴到pastebin中:http://pastebin.com/uHmYmhpT

看起来像这样:

<FF><FE>1^@^M^@
^@0^@0^@:^@0^@0^@:^@0^@9^@,^@4^@4^@2^@ ^@-^@-^@>^@ ^@0^@0^@:^@0^@0^@:^@1^@1^@,^@4^@4^@4^@^M^@
^@j& ^@W^@O^@K^@E^@ ^@U^@P^@^M^@
^@T^@H^@I^@S^@ ^@M^@O^@R^@N^@I^@N^@G^@ ^@j&^M^@
^@^M^@
^@2^@^M^@

......等等。

这显然不是ascii(或utf8)文本文件,因此大多数标准工具(sedgrepawk等)都无法使用。

开头的<FF><FE>Byte Order Mark,表示此文件是UTF16编码的文本。有一个用于在UTF16和UTF8之间进行转换的标准工具,UTF8与字母数字字符的ascii兼容,因此如果我们将其转换为UTF8,那么sed / grep / awk /等将能够编辑它。

我们需要的工具是iconv。遗憾的是,iconv没有就地编辑功能,因此我们必须编写一个使用临时文件进行转换的循环:

find . -type f -name '*.srt' -print0 | while read  -d '' filename; do
    if file "$filename"|grep -q 'UTF-16 Unicode'; then
        iconv -f UTF16 -t UTF8 -o "$filename".utf8 "$filename" && mv "$filename".utf8 "$filename"
    fi
done

然后,您可以运行find / sed命令将它们小写。大多数程序都不会关心你的文件现在是UTF8而不是UTF16,但如果你有问题,那么你可以编写一个类似的循环,使用iconv将它们放回UTF16后再缩小它们。


如果您只想小写所有匹配'* .txt'的文件:

sed -i 's/.*/\L&/' *.txt

但是请注意,如果有很多.txt文件,这会遇到命令行长度的问题。

如果你想递归地对所有文件进行小写,我会使用Diego的方法 - 但是有几个错误要修复:

find . -type f -exec sed -i 's/.*/\L&/' {} +

应该这样做。

如果你希望它是递归的,你希望它只影响'.txt'文件,你有{{1}的文件太多工作,然后使用:

sed ... *.txt

find . -maxdepth 1 -type f -name '*.txt' -exec sed -i 's/.*/\L&/' {} + 停止递归)

较旧版本的find不支持-maxdepth 1语法,因此如果您遇到问题,请将-exec ... +替换为+\;更可取,因为它使+每次调用多个文件调用find,而不是每个文件调用一次,因此效率稍高。

答案 1 :(得分:1)

没有测试过,但我认为这可以通过目录递归搜索,查看所有文件,并将其内容替换为小写版本:

find ./ -type f -exec sed -i ‘s/.+/\0\L/’ {} \;

答案 2 :(得分:1)

您可以编写一个简短的脚本,将“ .txt”形式的文件转换为“ -lowered.txt”:

#!/bin/bash
# lowerit.sh
in=$1
out=${in/.txt/-lowered.txt}
tr '[:upper:]' '[:lower:]' < $in > $out

如果要转换多个文件,当然不能将output.txt用于所有文件。你不能写入输入文件 - 这将截断它。

您可以写入中间文件,并将其重命名为最后的第二步。

要处理多个文件,请使用find:

find . -name "*.txt" -exec ./lowerit.sh {} +