
次のような入力があります:
Austin, Ashley D
Bender, Isaiah J
ここでは、名前を「、」まで切り取って、次に 2 番目の名前の最初の文字を追加しようとしています。
たとえば、上記の 2 つは Austina と Benderi になります。どなたか助けていただけませんか。
答え1
あなたはこれを で解決することに興味を示していますcut
。 でそれを実行する方法があるはずですパイプそして、いくつかの組み合わせcut
、tr
、 そして多分)paste
しかし、特に頭文字の大文字/小文字を変更する場合(たとえば、Ashleyの先頭の「A」が「Austina」の末尾の「a」になるなど)、 よりも汎用性の高いものを使用する方が簡単ですcut
。私は次のように提案します。Perlワンライナーこれは、主に名前に許可する文字に応じて、次のような形式になります。
perl -wpe 's/^(\w+),\s*(\w).*/$1\L$2/' file
これは警告を有効にして( )、Perlインタープリタを実行し-w
、入力を1行ずつ読み取り、各行でスクリプトを実行して結果を出力し(-p
)、そのスクリプトを次のコマンドライン引数から取得します( )。私が作成した-e
スクリプト自体は、s/^(\w+),\s*(\w).*/$1\L$2/
引用と一重引用符シェルは独自の拡張その上に、入力と一致する式がs/pattern/replacement/
パターンそして、一致した部分を交換。
の中に正規表現、^(\w+),\s*(\w).*
:
^
行の先頭に一致します。(\w+)
1つ以上の(+
) 単語文字 (\w
(下記参照)をキャプチャし((
)
) を最初のキャプチャ グループに追加します。,
文字通り一致します。\s*
0回以上一致します(*
) 空白文字 (\s
)。(\w)
単語の1文字に一致します(\w
(下記参照)をキャプチャし((
)
) を 2 番目のキャプチャ グループに追加します。.*
0回以上一致します(*
) 行に現れる任意の文字 (.
つまり、行の残りの部分と一致します。
次に、$1\L$2
一致したテキスト(行全体、した一致) を次のように置き換えます:
$1
最初のキャプチャ グループの内容を変更せずにそのまま返します。これは、人の姓を格納するためのフィールドです。\L$2
、2番目のキャプチャグループ( )の内容を$2
小文字に変換したもの(\L
これは、人の名を表す最初の文字です(ただし小文字になります)。
そのままでもうまくいくかもしれません。しかし:
\w
名前でどの文字を一致させたいかに応じて、パターン内のの両方の出現を変更する必要がある場合があります。\w
は、文字、数字、およびアンダースコア (_
) のみと一致します。多くの名前には、ダッシュやアポストロフィなど、これ以外の文字が含まれています。- また、文字として何が適格であるかという問題もあります(これは、時には異なる解決策ではありますが、より単純なツールにも当てはまります)。正規表現で文字のみを一致させる最適な方法は何ですか?これは、アクセント付きの文字、文字に付加される発音区別符号、およびラテン文字以外のアルファベットの文字を含む名前に関係します。
- 大文字と小文字の変換は、見た目よりも難しい問題です。異なる書き言葉には異なる文字があるだけでなく、同じ文字でも大文字と小文字の変換が異なります。
もう一つの非常に単純代わりに\w
私が思いつく選択肢は、名前に何でも含められるようにすることだ他の空白や--を に,
置き換えることで実現できます。\w
[^,\S]
[
]
文字クラス先頭の は^
クラスにすべてが含まれていることを意味しますしかし指定された文字(ない文字クラス外の意味に関連する)、,
文字通りに指定し、\s
すべての空白文字を指定します。
perl -wpe 's/^([^,\s]+),\s*([^,\s]).*/$1\L$2/' file
Perlの正規表現の詳細については、perldoc perlretut
そしてperldoc perlre
あなたが提示した問題はただ非常に複雑なので、基本的なテキスト処理ツールよりも洗練された (したがってより複雑な) ツールを使用する動機になります。おそらく、それらのツールでそれを実行する方法を見つけることができるので、そうするとしても責められません。しかし、これは将来のさらに複雑な問題にも役立つと思います。
答え2
cut、pipes、tr、paste、(および sed) を使用した推奨される解決策は次のようになります。
cut -f1 -d, foo >bar; cut -f2 -d" " foo | cut -c1 |tr "A-Z" "a-z" >bar2 ;paste bar bar2|sed -e "s/\x9//g"
foo は入力ファイルです。したがって、cut などを使用してタスクを管理できますが、pearl ソリューションの方がエレガントで適切です。