使用管道读取文件,运行脚本并写入同一文件

时间:2013-04-21 14:25:14

标签: bash

我需要编写一个脚本,其中一行获取文件,并在每行末尾的同一文件上打印句子上的单词数量,只有单词“单词”出现在它上面。我可以使用另一个可以做任何我想要的脚本。 我的问题是,在运行脚本后,文件为空,即我发送给脚本的文件。

这是一行脚本:

#!/bin/bash
cat $1 | ./words_num word | cat $1

words_num

#!/bin/bash
while read line; do
    temp=`echo $line | grep $1 | wc -l`
    if (($temp==1)); then
        word_cnt=`echo $line | wc -w`
        echo "$line $word_cnt" 
    else 
        echo "$line"
    fi  
done

例如,在文件之前:

bla bla blaa word
words blaa
bla bla

文件后:

bla bla blaa word 4
words blaa 2
bla bla

你能帮忙吗?

2 个答案:

答案 0 :(得分:4)

单线:

cat $1 | ./words_num word | cat $1

很奇怪。它大致相当于:

cat $1 | ./words_num word >/dev/null; cat $1

这不太可能是预期的结果。它也是UUOC(无用cat)奖的候选人。

如果打算用修改后的版本覆盖原始文件,那么你应该写一下:

./words_num word < $1 > tmp.$$; mv tmp.$$ $1

如果你想在屏幕上看到结果,那么:

./words_num word < $1 | tee tmp.$$; mv tmp.$$ $1

如果被打断,这些都会留下一个临时文件。您可以通过以下方式避免这种情况:

#!/bin/bash
trap "rm -f tmp.$$; exit 1" 0 1 2 3 13 15
./words_num word < $1 | tee tmp.$$
mv tmp.$$ $1
trap 0

陷阱设置信号处理程序(EXIT,HUP,INT,QUIT,PIPE,TERM)并删除临时文件(如果存在)并以失败状态退出。最后的trap 0取消退出陷阱,以便命令成功退出。

至于words_num脚本,似乎需要awk而不是shell:

#!/bin/bash
[ $# == 0 ] && { echo "Usage: $0 word [file ...]" >&2; exit 1; }
word=$1
shift
awk "/$word/"' { print $0, NF; next } { print }' "$@"

如果您正在使用awk脚本编写代码,可以减少这种情况,但我更喜欢澄清代码。它查找包含该单词的行,打印该行以及该行中的字段数,然后移动到下一行。如果线条不匹配,则只需打印即可。赋值和移位意味着"$@"包含words_num的所有其他参数,awk将自动遍历命名文件,或者如果没有命名文件则读取标准输入。

脚本应该检查给定的单词不包含任何斜杠,因为这会弄乱正则表达式(可以用[/]替换每个出现的字符串,这是一个只包含斜杠的字符类。该级别的防弹保留给感兴趣的用户。

答案 1 :(得分:1)

cat $1 | ./words_num word | tee $1