私はスクリプトに初めてアクセスし、Linuxターミナルコースを受講しています。私たちはLinuxディストリビューションUbuntuを使用しています。今週の課題の一部として、列があるタイムシートのテキストファイルで、特定の時点で特定の部門で働いている従業員を特定する必要がgrep
あります。awk
これを困難にする迷惑な部分は、時間が時間から分離されているため、AM/PM
時間を簡単に把握することが不可能であるということです。時間を配置すると、05:00:00
ワーカーAM
と行の両方が表示されるためです。PM
解決策が見つかりました。以下を入力してください。
grep -i ‘05:00:00 AM’ file.txt
これは私に効果的で、私に必要な行を与えました。
05:00:00 AM
問題は、必要に応じて時間を変更できるようにスクリプトで使用し、パラメータ/変数を使用する必要があることです。しかし、‘$1’
スクリプトを入れようとすると
grep -i '$1' 0310_Dealer_schedule | awk -F " " '{print $5} {print $6}'
赤で強調表示され、黄色で強調表示に変わります。
その後、実行しようとすると、grepはそれを私が探しているディレクトリまたはファイル05:00:00 AM
として扱います。AM
$1
次に、スクリプトに引用符を使用しないようにしました。その後、スクリプトを実行しようとしたときに次のことを実行しました。
sh scriptname.sh ‘05:00:00 AM’
これも私にエラーを与えた“AM directory does not exist”
したがって、成功した実行方法があるかどうかを知りたいです。
grep -i ‘05:00:00 AM’ file.txt | awk
-F “ “ ‘{print $5} {print $6}’
ただし、whereは05:00:00 AM
それを変数にして時間とまたはAM
を変更できますPM
。
なぜ引用符やアポストロフィのある項目が黄色に変わるのかわかりません。
私のスクリプトの目的は、変数を入力したときに作業している管理者の名前を生成することです。私が言ったように、私を悩ませる唯一のことは、sumを含むすべての行を05:00:00 AM
印刷せずにgrepを試すことです。引き続き行を印刷したいと思います。05:00:00
AM
05:00:00 AM
以下は、私が探している文書の例です。結果が合うことを願っています。
TIME AM/PM TELLERS MANAGER
05:00:00 AM J. Doe C. Jones
06:00:00 AM J. Doe C. Jones
07:00:00 AM J. Doe C. Jones
08:00:00 AM J. Doe C. Jones
09:00:00 AM J. Doe C. Jones
10:00:00 AM J. Doe C. Jones
11:00:00 AM J. Doe C. Jones
12:00:00 PM A. Smith D. MILLER
01:00:00 PM A. Smith D. MILLER
02:00:00 PM A. Smith D. MILLER
03:00:00 PM A. Smith D. MILLER
04:00:00 PM A. Smith D. MILLER
05:00:00 PM A. Smith D. MILLER
助けてくれてありがとう。
編集:プレビューすると、文書が複数の列に分割されないことがあります。しかし、ドキュメントでは列で区切られています。
TIME AM/PM TELLERS MANGER
答え1
"
たとえば、変数の周りに二重引用符を追加すると、シェルは変数を拡張できますが、"$1"
grepはまだ変数を単一の引数として解釈します。
答え2
拡張正規表現(ERE)を使用して簡単に保ちます。
スクリプトで最初の引数($1
)として時間を入力し、2番目の引数($2
)としてAMまたはPMを入力します。したがって、grep
次のように命令を作成できます。
grep -i -E "$1[[:blank:]]+$2" infile
- 「infile」には処理したい内容が含まれています。
-E
拡張正規表現フラグです。[[:blank:]]
スペースまたはタブを表します。+
これは、ERE の前に表示される項目が 1 回以上表示される必要があることを意味します。
しかし、上記は全体の行を印刷します。管理者の名前だけを出力するには、awk
notgrep
と次のものを使用してくださいawk
。
awk -v time=$1 -v suffix=$2 'BEGIN {pattern_ere=time"[[:blank:]]+"suffix} $0 ~ pattern_ere {print $5, $6}' infile
... awk
FS=OFS=" " のデフォルト値が変更されずに保持されると仮定します。
答え3
以下のスクリプトをお試しください。素晴らしい作品。
#!/bin/bash
m=$1
q=$2
awk -v m="$m" -v q="$q" '$1 == m && $2 == q {print $5,$6}' file
出力
sh script.sh 05:00:00 AM
C. Jones
クォータがあります。
変数mの最初の位置引数 変数qの2番目の位置引数
最後のステップでは、この変数を使用してファイルの列1と列2を比較します。
答え4
まず、考慮する必要があるいくつかの要素があります(この例では、単にシェルスクリプトを呼び出し、代わりにmyscript
単に実行するように設定されているとします)。myscript
sh myscript
まず、ユーザーがコマンドを実行する方法を検討します。ユーザーがmyscript "05:00:00 AM"
、またはmyscript 05:00:00 AM
、またはさらにmyscript 5:00 AM
?つまり、二重引用符を使用してコマンドラインに内容全体を1つの引数として処理するように指示しますか、または引用符を省略して2つの引数として処理しますか?常に2桁の数字を使用し、必要に応じて前にゼロを追加しますか?常に時間、分、秒を提供しますか(AM / PMを指定しないとどうなりますか?)
すべての問題に解決策がありますが、単純化のために常に入力する必要があると主張します。myscript "hh:mm:ss xx"
ここで、hh、mm、およびssは常に2桁です(有効な時間も含まれるため、42
「hh」には無効です)。 「xx」は「am」または「pm」です。また、「AM / PM」は大文字、小文字である可能性があり、ビールを飲みすぎて「aM」を入力した可能性があります...)そして、他のすべての作業は、単にgrep / awk / etcに大文字と小文字を区別するモードで実行するように指示することによって行うことができます(すでに行ったように-iフラグを使用)。
上記の前提条件を使用して与えられた行は次のgrep -i '$1' 0310_Dealer_schedule | awk -F " " '{print $5} {print $6}'
とおりです。ほぼ正しい。 (追加編集:ここで「正しい」とは、あなたが提供したものとまったく同じ意味です。同じものをより効率的にエンコードする別の方法があります。)考えるはいgrep -i "$1" 0310_Dealer_schedule | awk -F " " '{print $5} {print $6}'
。
違いは、コマンドラインやスクリプトなど、さまざまな場所で使用される引用符の種類にあります。
テスト用に行った作業は次のとおりです。
スクリプトファイルの名前は「myscript」(直接実行可能にしたため、.sh拡張子はありません)で、次のものを含みます(他の部分で使用されている他の引用符に注意してください!)。
#!/bin/env bash
grep -i "$1" data.txt | awk -F " " '{print $5} {print $6}'
あなたのデータを「data.txt」というファイルに入れました。コマンドと出力は次のとおりです。
$ ./myscript "05:00:00 AM"
C.
Jones
期待どおりに動作します。
したがって、ここで唯一の実際の問題は、異なる引用が異なる部分にどのように影響するかを理解しようとしているようです。
awk
追加するように編集されました:また、パイプの側面に焦点を当てたcbhiheの投稿にある情報にも注意してください。パイプの対応する側面はその側面の出力に依存するため、最初は使用awk
(または他のもの)について言及しませんでした。grep