Bashスクリプトを使用した関数の作成

Bashスクリプトを使用した関数の作成

私は以下のコードを開発しており、将来の要件に合わせてこのコードを改善したいと思います。だから、関数を使うと、コードは今よりずっと良くなり、非常に体系的に見えると思いました。

それでは、手順または組織化されたコードブロックにどのように移動しますか?

私を助けてくれますか?

バージョン:Red Hat Enterprise Linuxサーバーバージョン7.3(Maipo)

(出力は同じでなければなりません)

 #!/bin/bash

 hammer host list >| host.list
 cat host.list | grep "RHEL Server" | awk -F'|' '{ print $3}' |  sort > 
 host.modified1
 grp=`sort host.modified1 | uniq -c`
 echo "Linux Versions Grouped by Count" > host.modified1
 echo "" >> host.modified1
 echo "$grp"  >> host.modified1
 echo "" >> host.modified1
 echo "Linux Versions and Hostnames" >> host.modified1
 echo "" >> host.modified1
 cat host.list | grep "RHEL Server" | awk -F'|' '{ print $3"|"$2  }' | sort 
 >> host.modified1

出力;

  Linux Versions Grouped by Count

  8  RHEL Server 6.5  
 21  RHEL Server 6.6  
  1  RHEL Server 6.7  
 10  RHEL Server 6.8  
 39  RHEL Server 6.9  
 19  RHEL Server 7.2  
 34  RHEL Server 7.3  
 30  RHEL Server 7.4  


Linux Versions and Hostnames

RHEL Server 6.5  | xxx.dnsname 

答え1

必要に応じて、私は確かに関数に入れることができます。ここに例があります。また、実行中の処理を減らそうとします。出力がどのように見えるかわからないので、hammer host list元のコードに基づいて推測しました。

do_stuff () {    
    local tmpfile=$(mktemp)
    hammer host list | grep -F 'RHEL Server' >"$tmpfile"

    printf 'Linux Versions Grouped by Count\n\n'
    awk -F '|' '{ c[$3]++ } END { for (h in c) printf("%d\t%s\n", c[h], h) }' "$tmpfile" | sort -k 2

    printf '\n\nLinux Versions and Hostnames\n\n'
    awk -F '|' '{ printf("%s | %s\n", $3, $2) }' "$tmpfile" | sort

    rm -f "$tmpfile"
}

do_stuff >rhel_things.txt

この関数はすべてを標準出力に書き込み、関数が呼び出されるとその出力がリダイレクトされます。一時ファイルを使用して出力を保存し、hammer完了したら出力を削除します。


詳しく分析したい場合は、次の手順を実行してください。

pre_parse () {    
    local tmpfile=$(mktemp)
    hammer host list | grep -F 'RHEL Server' >"$tmpfile"

    printf '%s\n' "$tmpfile"
}

do_group_counts () {
    local infile="$1"

    printf 'Linux Versions Grouped by Count\n\n'
    awk -F '|' '{ c[$3]++ } END { for (h in c) printf("%d\t%s\n", c[h], h) }' "$infile" | sort -k 2
}

do_ver_and_hosts () {
    local infile="$1"

    printf 'Linux Versions and Hostnames\n\n'
    awk -F '|' '{ printf("%s | %s\n", $3, $2) }' "$infile" | sort
}

tmpfile=$( pre_parse )

{
    do_group_counts "$tmfile"
    printf '\n\n'
    do_ver_and_hosts  "$tmpfile"
} >rhel_stuff.out

rm -f "$tmpfile"

答え2

awk以下のようなプログラムにすればいいと思います。一見すると実際より長く見えますが、説明的な長い変数名を使用し、良心的に可能であればすぐにメモリを解放するからです。

  1. awk強力な基本ソート機能が組み込まれているため、外部プログラムにパイプする必要はありません。

  2. awkasort関数はオプションのasorti3番目の引数も取ります。ソート方法@ind_num_asc、、、、などにすることができ、昇順または降順にソート@ind_num_descするさまざまな方法で使用されます。いつものようにページを確認してください。@ind_num_asc@ind_num_descman

  3. deleteメモリ使用量を説明するために、プログラムはステートメントで埋められ、データセットが大きくなるにつれて問題になる可能性があります。

  4. 使用するサンプル入力データを提供していないのは残念です。コーディングしながら楽しい時間を過ごしましたが、入力データなしで機能するのにどれだけ近いのかは信じています。基本的なポイントは、最も効率的な方法はおそらくawk単一のプログラム内にあるということです。

hammer host list \ | awk -F'|' ' \ BEGIN {i=0} /RHEL Server/ { unsorted_count[$3]++ unsorted_list[i++]=$3"|"$2 } END { printf "\nLinux Versions Grouped by Count\n\n" i=0 for (release in unsorted_count) count_list[i++]=unsorted_count[release]"\t"release delete unsorted_count n=asort(count_list,sorted_count) delete count_list for (i=1; i<=n; i++) printf "%s\n", sorted_count[i] delete sorted_count printf "\n\nLinux Versions and Hostnames\n\n" i=0 for (hostname in unsorted_list) host_list[i++]=unsorted_list[hostname]" | "hostname delete unsorted_list n=asort(host_list,sorted_list) delete host_list for (i=1; i<=n; i++) printf "%s\n", sorted_list[i] }'

関連情報