2016-06-15 3 views
0

grepを使用してファイルから数字を抽出しました.1 2 3 5 6 11 18とします。ミスを1..20にするには、ファイルに入れてcommを使って比較します。シーケンス中に欠けている数字を抽出する

1 
10 
    11 
12 
13 
14 
15 
16 
17 
    18 
19 
    2 
20 
    3 
4 
    5 
    6 
7 
8 
9 

を出力

a='1 2 3 5 6 11 18' 
printf '%d\n' $a | sort -u > 111 
printf '%d\n' {1..20} | sort -u > 222 
comm 111 222 
rm 111 222 

は、ファイルに保存せずに、より便利な方法はありますか?

+0

[プロセス置換](http://mywiki.wooledge.org/ProcessSubstitution): 'comm <(printf '%d \ n' $ a | sort -u)<(printf '%d \ n' {1 ..20}) 'サイドノート:' {1..20} 'の場合、ソートは必要ありません。彼らはすでに分類されています。 – anishsane

+0

^^そう言えば、純粋なbashの亜種は簡単に書くことができます: 'a = '1 2 3 5 6 11 18'; $ aのxのために; do [$ x] = 1;完了しました。 for((x = 1; x <= 20; x ++)); do((t [i]))||エコー$ i; done' – anishsane

+0

ありがとう@anishsane。しかし、2行目はヌルラインを出力します。最初のものは 'ソート'が必要です。 '1 2 3 4 ... 10 ... 20'はソートされているとはみなされませんが、' 1 10 11 ... 2 20 3 ... 'はソートされていません。 – Lee

答えて

3

あなたは20かかわらず、1から数字を反復し、その後aに対して各数を比較するために正規表現を使用することができます。

a='1 2 3 5 6 11 18' 
for i in {1..20}; do 
    re="\\b$i\\b" 
    [[ "$a" =~ $re ]] || echo "$i" 
done 

正規表現は非常に簡単です:\bword boundaryあり、そして$iはに拡大します1,2、...、20

上記は、aにないすべての数字を出力します。

+0

こんにちは@andlrcは動作しますが、なぜ2つのバックスラッシュが1つだけではないのか分かりません。なぜ[["$ a" =〜 "\\ b $ i \\ b"]] || echo "$ i" 'は機能しません。 – Lee

+1

理論上、\ b" 'は動作するはずですが、バックスラッシュはエスケープ文字であるため、' \\ b' - > '\ b'をエスケープするか、一重引用符: ''\ b'" $ i "'\ b''。なぜ[["$ a" =〜 "\\ b $ i \\ b"]] 'は動作しません:bashのバグだと思われます。正規表現?](http://stackoverflow.com/a/12696899/887539) – andlrc

関連する問題