5

ファイルを取得する 1 行のスクリプトを記述し、同じファイルの各行の終わりに、「単語」という単語が表示される場合にのみ文の単語数を出力する必要があります。やりたいことが何でもできる別のスクリプトを使用できます。私の問題は、スクリプトを実行した後、スクリプトに送信したファイルが空であることです。

これは 1 行のスクリプトです。

#!/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

手伝ってくれますか?

4

2 に答える 2

5

ワンライナー:

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

独特です。これは、次とほぼ同等です。

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

これは意図した結果である可能性は低いです。catまた、UUOC (Useless Use of ) 賞の候補でもあります。

元のファイルを修正版で上書きすることが意図されている場合は、おそらく次のように記述する必要があります。

./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:

#!/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

スクリプトは、指定された単語にスラッシュが含まれていないことを確認する必要があります。これは、正規表現を混乱させるためです (表示される各単語を[/]、スラッシュのみを含む文字クラスである に置き換えても問題ありません)。そのレベルの防弾は、関心のあるユーザーに委ねられています。

于 2013-10-23T17:38:50.460 に答える
3
cat $1 | ./words_num word | tee $1
于 2013-04-21T14:33:28.117 に答える