我想从文件中删除所有非英文字母数字。
tr -sc '[:alnum:][:punct:]' ' ' <file
gawk
并sed
有-i
标志,但我在手册页中找不到类似的内容tr
。
我如何就地执行此操作,即将输出存储在输入文件本身中?
答案1
没有。很少有命令具有此功能,GNU awk ( gawk
) 最近才添加它,即使对于那些具有-i
或等效功能的命令,它所做的只是在后台创建一个临时文件。
所以,做到这一点的方法是:
tr -sc '[:alnum:][:punct:]' ' ' <file >newfile && mv newfile file
如果你经常需要这个功能,你可以启动一个小功能:
tri(){
tmpFile=$(mktemp)
echo "$@"
case $# in
## You've given tr options
4)
trOpts="$1"
set1="$2"
set2="$3"
inputFile="$4"
;;
## No options, only set1 and set2 and the input file
3)
set1="$1"
set2="$2"
inputFile="$3"
;;
## Something wrong
*)
echo "Whaaaa?"
exit 1
;;
esac
tr "$trOpts" "$set1" "$set2" < "$inputFile" > "$tmpFile" &&
mv "$tmpFile" "$inputFile"
}
然后您可以将其运行为:
tri -sc '[:alnum:][:punct:]' ' ' file
请注意,与 real 不同tr
,这需要文件名作为参数而不是重定向输入 ( <file
),并且选项如上所示一起指定(而不是像-s -c
)。
答案2
由于该tr
命令写入的数据最多与读取的数据一样多,因此将其输出写入到位应该是安全的:
带壳ksh93
:
tr -sc '\n[:alnum:][:punct:]' '[ *]' < file 1<>; file
(此处转换为标准/POSIX 语法[ *]
,并将换行符添加到要保留的字符列表中,以避免创建非文本输出)。
ksh931<>;
特定的运算符类似于标准的1<>
读+写而不截断运算符,只不过在成功完成重定向的命令后,文件将在当前位置截断。