-2

脚本应该读取路径中的每个文件并替换每一行中的字符串。如何在我在同一路径中迭代 10 个不同的输入文件名时创建临时文件和 mv 替换请建议

SunOS 5.10

FILES=/export/home/*.txt
for f in $FILES
do
echo "Processing $f file..."
cat $f | awk 'BEGIN {FS="|"; OFS="|"} {$8=substr($8, 1, 6)"XXXXXXXXXX\""; print}'
done

输入文件

"2013-04-30"|"X"|"0000628"|"15000231"|"1999-12-05"|"ST"|"2455525445552000"|"1111-11-11"|75.00|"XXE11111"|"224425" 
"2013-04-30"|"Y"|"0000928"|"95000232"|"1999-12-05"|"VT"|"2455525445552000"|"1111-11-11"|95.00|"VVE11111"|"224425"

输出文件

"2013-04-30"|"X"|"0000628"|"15000231"|"1999-12-05"|"ST"|"245552xxxxxxxxxx"|"1111-11-11"|75.00|"XXE11111"|"224425" 
"2013-04-30"|"Y"|"0000928"|"95000232"|"1999-12-05"|"VT"|"245552xxxxxxxxxx"|"1111-11-11"|95.00|"VVE11111"|"224425"

不知道如何使用这个

cat $f | awk 'BEGIN {FS="|"; OFS="|"} {$8=substr($8, 1, 6)"XXXXXXXXXX\""; print}' $f > tmp.txt && mv tmp.txt $f
4

1 回答 1

0

为了达到您想要的最终结果,您可以使用ed而不是awk

FILES=/export/home/*.txt
for f in $FILES; do
    echo "Processing ${f} file..."
    ed  "${f}" <<EOF
% s/\([0-9]\{6\}\)[0-9]\{10\}/\1xxxxxxxxxx/
w
q
EOF
done

这需要更少的步骤(即命令调用),因为您没有创建临时文件并移动它。相反,您正在使用所需的更改编辑文件,然后将其关闭。

% 表示“在每一行上操作”(不要担心不匹配的行)
s 表示“执行替换” -- /[pattern]/[replacement]/
w 表示写
q 表示退出
EOF 关闭“这里的文档”

希望有帮助。

编辑说明:Charles Duffy指出ed ${f}会在包含空格的文件名上失败,而ed "${f}"不会受到这种特殊缺陷的影响。这是真实的。然而,情况也是如此,上面的for循环可能会拆分文件名中的任何空格。您可以设置IFS ( IFS='\n') 来绕过对 KSH、BASH、MKSH、ASH 和 DASH 的限制。在 ZSH(取决于您的版本)中,您可能需要设置 SH_WORD_SPLIT。作为替代方案,您可以使用read从for循环更改为while循环:

FILES=/export/home/*.txt
ls ${FILES} | while read f; do
    echo "Processing ${f} file..."
    ed  "${f}" <<-EOF
% s/\([0-9]\{6\}\)[0-9]\{10\}/\1xxxxxxxxxx/
w
q
EOF
done

编辑注意:我上面的错误陈述受到了打击,但出于历史目的而保留。请参阅 Charles Duffy(下文)的评论以进行澄清。

于 2014-02-16T06:03:23.790 回答