個人情報を含むファイル(.txt)があります。ターミナルを介してファイルからいくつかの詳細のみをコピーし、それらを新しい.txt
ファイルに入れるにはどうすればよいですか?
たとえば、これがファイルのコンテンツの場合:
name : farah age : 23 phone number : 0123 education : degree
年齢と電話番号のみをコピーして新しい.txt
ファイルに出力するにはどうすればよいですか?
個人情報を含むファイル(.txt)があります。ターミナルを介してファイルからいくつかの詳細のみをコピーし、それらを新しい.txt
ファイルに入れるにはどうすればよいですか?
たとえば、これがファイルのコンテンツの場合:
name : farah age : 23 phone number : 0123 education : degree
年齢と電話番号のみをコピーして新しい.txt
ファイルに出力するにはどうすればよいですか?
回答:
これを行うにはいくつかの方法があります。ファイルに既知の構造がある場合は、を使用できますgrep
。このgrep
コマンドは、ファイルで特定のフレーズを検索し、そのフレーズに一致する行を返します。ファイルが次のように見える場合
名前:サリー
生年月日:7.31.76
住所:1234 Main St.
SSN:123-45-6789
あなたが実行することができgrep Name info.txt
、それが返されName: Sally
ます。その後、出力を別のファイルにリダイレクトできます。だから
grep Name info.txt > info2.txt
行を新しいファイルinfo2.txtに出力します。新しい行を追加する場合は、次のことができます
grep Address info.txt >> info2.txt
そうでない場合、ファイルは上書きされます。
入力ファイルに次のものdetails.txt
が含まれていると仮定します。
name: farah
age: 23
phone number: 0123
education: degree
拡張grepで「名前」と「電話」の行を選択し、出力をnew.txtにリダイレクトできます。
grep -E "age:|phone number:" details.txt > new.txt
これにより、new.txtが生成されます。
age: 23
phone number: 0123
使い方:
Grepは一致した行のみを出力します。-E
オプションはあなたに使用する可能性与え拡張正規表現が有効|
(代替)。パターン全体を引用することを忘れないでください|
。grepによって解釈されます。それ以外の場合、シェルは解釈を試みます。ここではこれは必要ありません。
示したファイルには、すべての詳細が1行で記載されています。
name : farah age : 23 phone number : 0123 education : degree
age :
コマンドにハードコードなどを記述できると仮定しましたが、それに続くテキストはさまざまであり、詳細は指定された順序ではないか、連続していない可能性があります。
grep
の-o
フラグを使用して行の一部を抽出できます。これは、行全体ではなく、一致した部分のみを出力します。
age :
とのphone number :
部分を含める場合は、-e
フラグを使用して複数の一致を指定するか、代替を使用できます。
$ grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file
age : 23
phone number : 0123
この表現[^ ]*
は、スペースではない任意の数の文字を意味age :
するため、次のスペースまでの文字に一致します。
file
詳細を含むファイルの名前に置き換えます。次の>
ように、演算子を使用して出力を新しいファイルにリダイレクトすることにより、新しいファイルを書き込むことができます。
grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file > outfile
その場合、出力は表示されません。最初に出力を確認してから、リダイレクトを追加する必要があります。
これが交互の例です。-E
フラグを使用して、grep
拡張正規表現を使用するように指示します。構文は次のとおりです(pattern1|pattern2)
-これはpattern1
および/またはに一致しpattern2
ます。どちらかが見つかった場合、(もう一方が見つかったかどうかに関係なく)印刷されます。現在+
、*
0個以上の先行文字を意味する代わりに、少なくとも1つの先行文字の意味を使用しています。このコンテキストでは、どちらも同等に機能します。
$ grep -Eo '(age : [^ ]+|phone number : [^ ]+)' file
age : 23
phone number : 0123
age :
and phone number:
部分を省略したい場合は、-P
フラグgrep
を使用してPerl互換の正規表現を使用するように要求できます。これは、交替をサポートし、特定のパターンの後にテキストを一致させる方法もサポートします。
$ grep -Po '(age : \K[^ ]+|phone number : \K[^ ]+)' file
23
0123
テキストのフォーマットを変えたい場合は、次のように使用できますsed
。
$ sed -r 's/.*(age) : ([^ ]*).*(phone number) : ([^ ]*).*/\1:\2 | \3:\4/' file
age:23 | phone number:0123
これはのage
前phone number
に依存しているため、そうでない場合は適宜調整してください。順序に依存できない場合は、次の非常に複雑なコマンドを使用できます。
$ sed -r 's/(.*)(phone number : [^ ]+)(.*) .*/\2 \1\4/; s/(phone number) : ([^ ]+) .*(age) : ([^ ]+).*/\1: \2 | \3: \4/' file
phone number: 0123 | age: 23
これにより、各行のphone number :
最初にセクションが来るように行が再配置され、次に2回目の置換が行われて目的の詳細が選択されます。ここで使用したテクニックは、muruによるこの答えに負うものです。
sed
以前の説明でカバーされていないコマンドに関する注意-r
より読みやすいコマンドには拡張正規表現を使用します(GNU は同じ意味でsed
理解-E
します)s/old/new/
置き換えるold
とnew
(pattern)
またはなどでpattern
、後で参照するために保存します(キャプチャグループが発生する左から右の順序に対応します- これらのうち最大7つしか保持されないことに注意してください!)。\1
\2
sed
.
任意の文字。したがって、.*
任意の数の任意の文字を表します。;
シェルのように、コマンドを区切ります。