我有一个相当大的SQL文件,以FFFE的字节顺序标记开始。 我已经使用unicode感知的linux拆分工具将此文件拆分为100,000行块。 但是,当它们返回给窗口时,它不会像第一个窗口以外的任何部分那样,因为只有它具有FFFE字节顺序标记。
我怎样才能使用回声(或任何其他bash命令)添加这两个字节的代码?
像(备份第一)):
for i in $(ls *.sql) do cp "$i" "$i.temp" printf '\xFF\xFE' > "$i" cat "$i.temp" >> "$i" rm "$i.temp" done
基于sed的Anonymous解决方案 , sed -i '1s/^/\xef\xbb\xbf/' foo
将BOM添加到UTF-8编码文件foo
。 有用的是,它也可以将ASCII文件转换为带有BOM的UTF8
对于一个通用的解决方案,无论文件是UTF-8,UTF-16还是UTF-32,我都会使用vim的'bomb'
选项设置正确的字节顺序标记:
$ echo 'hello' > foo $ xxd < foo 0000000: 6865 6c6c 6f0a hello. $ vim -e -s -c ':set bomb' -c ':wq' foo $ xxd < foo 0000000: efbb bf68 656c 6c6f 0a ...hello.
( -e
表示以ex模式而不是可视模式运行; -s
表示不打印状态消息; -c
表示“执行此操作”)
要将BOM添加到以“foo-”开头的所有文件中,可以使用sed
。 sed
有一个选项来进行备份。
sed -i '1s/^\(\xff\xfe\)\?/\xff\xfe/' foo-*
这个显示sed会创建一个名称以“sed”开头的临时文件。 如果您确定已经确定没有BOM,则可以简化命令:
sed -i '1s/^/\xff\xfe/' foo-*
确保你需要设置UTF-16,因为即UTF-8是不同的。
试试uconv
uconv --add-signature
Matthew Flaschen的答案是好的,但是它有一些缺陷。
ls
是不必要的。 当然,你可能会非常偏执,并在开始时检查临时文件的存在,所以你不会意外地覆盖它和/或使用UUID或生成的文件名。 mktemp,tempfile或uuidgen中的一个可以做到这一点。
td=TMPDIR export TMPDIR= usertemp=~/temp # set this to use a temp directory on the same filesystem # you could use ./temp to ensure that it's one the same one # you can use mktemp -d to create the dir instead of mkdir if [[ ! -d $usertemp ]] # if this user temp directory doesn't exist then # then create it, unless you can't mkdir $usertemp || export TMPDIR=$td # if you can't create it and TMPDIR is/was fi # empty then mktemp automatically falls # back to /tmp for file in *.sql do # TMPDIR if set overrides the argument to -p temp=$(mktemp -p $usertemp) || { echo "$0: Unable to create temp file."; exit 1; } { printf '\xFF\xFE' > "$temp" && cat "$file" >> "$temp"; } || { echo "$0: Write failed on $file"; exit 1; } { rm "$file" && mv "$temp" "$file"; } || { echo "$0: Replacement failed for $file; exit 1; } done export TMPDIR=$td
陷阱可能比我添加的所有单独的错误处理程序更好。
毫无疑问,所有这些额外的警告对于一次性脚本来说是过分的,但是当推动推进时这些技术可以节省您,特别是在多文件操作中。
$ printf '\xEF\xBB\xBF' > bom.txt
然后检查:
$ grep -rl $'\xEF\xBB\xBF' . ./bom.txt