テキスト付きのファイルがあります:
1861_ASSET-D_T_201702181000-201702181045_HN_
197895_STRING-H_T_201702181000-201702181045_HN_
14512861_FILE-FD_T_201702181000-201702181045_HN
Egrep、awk、またはsedを使用して、最初と2番目に一致する「_」の間にテキストを割り当てるにはどうすればよいですか?
私が欲しい:
ASSET-D
STRING-H
FILE-FD
awk
を次のパラメーターとともに使用できます。
-F "_"
-_
を区切り文字として使用します'{print $2}'
-2番目の要素を出力します
$ awk -F "_" '{print $2}' input_file
ASSET-D
STRING-H
FILE-FD
$ sed -r 's/[^_]+_([^_]+)_.*/\1/' file
ASSET-D
STRING-H
FILE-FD
-r
EREを使用s/old/new/
old
をnew
に置き換えます[^_]+
アンダースコアではない文字(some chars)
保存some chars
後で使用.*
任意の数の任意の文字\1
保存されたパターン他のツールを許可する場合は、cut
が最も簡単なソリューションになります。
cut -d _ -f 2 < input.txt > output.txt
いくつかのPerlアプローチ:
$ Perl -F_ -lae 'print $F[1]' file
ASSET-D
STRING-H
FILE-FD
-a
はPerlをawkのように動作させ、-F
で指定された文字で各入力行を分割し、結果の各フィールドを配列@F
に保存します。したがって、$F[1]
を印刷すると、2番目のフィールドが印刷されます(配列は0からカウントを開始します)。
代わりに:
$ Perl -pe 's/.*?_(.+?)_.*/$1/' file
ASSET-D
STRING-H
FILE-FD
-p
は、「-e
」で指定されたスクリプトを実行した後、すべての入力行を印刷することを意味します。 s/from/to/
は置換演算子です。 from
をto
に置き換えます。ここでは、0個以上の文字(.*
)と一致していますが、「貪欲でない」(.*?
)にしています。 ?
は、最短一致で停止します。したがって、.*?_
は最初の_
までのすべてに一致します。次の部分(.+?)_
は、次の_
まで1つ以上の文字と一致し、行の最後(.*
)まで他のすべてと一致します。括弧は一致を「キャプチャ」し、演算子の置換側で$1
として使用できるようにします。したがって、全体が行全体を括弧内にあるもので置き換えるだけです。
grep
でこれを行うこともできます:
$ grep -oP '^.*?_\K[^_]+' file
ASSET-D
STRING-H
FILE-FD
-o
は「一致した各行の一部のみを印刷する」ことを意味し、-P
は\K
を提供するPerl互換正規表現(PCRE)をオンにします。 \K
は、「この時点までに一致するすべてを無視する」ことを意味します。これは、最初の^.*?_
まで_
を使用してすべてを一致させ、次に\K
を使用して破棄して印刷されないことを意味します。次に、必要なだけの_
文字を必要なだけ([^_]+
)必要とします。
pythonワンライナーとして:
python3 -c "[print(l.split('_')[1]) for l in open('f')]"
ここで、'f'
は引用符で囲まれたファイルです。例:
python3 -c "[print(l.split('_')[1]) for l in open('/home/jacob/blub')]"
ASSET-D
STRING-H
FILE-FD
for l in open('f')
f 行ごとを読み取り、
l.split('_')[1]
行を区切り文字_
で分割し、2番目の文字列を保持します(インデックス[1]
、[0]
は最初です)。
print(l.split('_')[1])
その後、見つかった文字列を出力します。