我需要编写一个脚本,其中一行获取文件,并在每行末尾的同一文件上打印句子上的单词数量,只有单词“单词”出现在它上面。我可以使用另一个可以做任何我想要的脚本。 我的问题是,在运行脚本后,文件为空,即我发送给脚本的文件。
这是一行脚本:
#!/bin/bash
cat $1 | ./words_num word | cat $1
#!/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
你能帮忙吗?
答案 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