|
[パイプ]区切り文字を含む入力文字列があり、空の文字列の3番目と5番目の列を&
文字に置き換えるのが好きです。
入力ファイル:
a a|b b|c c|d d|e e
f f|g g|h h|i i|j j
出力ファイル:
a a|b b|c&c|d d|e&e
f f|g g|h&h|i i|j&j
cc, ee, hh and jj
の間のスペースが&
に置き換えられていることがわかります。while loopを使用してファイルを読み取り、cut
コマンドを使用する別のソリューションがあります。区切り文字を使用して、位置に基づいて変数に格納し、sed
を使用してスペースを「&」で置き換え、分割されたすべての変数を1つの変数に追加し、新しいファイルに追加します。これを達成するために使用できる単一のコマンドはありますか?
これにはawk
を使用します。
awk -F\| '{gsub(" ","\\&",$3); gsub(" ","\\&",$5)}1' OFS=\| infile.txt
-F\|
は、フィールドが|
パイプで区切られていることを「awk」に通知します(\
によってシェルにエスケープされないため、 pipeline stdin
として解釈されません)。 -F"|"
または-F'|'
のいずれか)。
gsub("regexp","replacement"[, INDEX])
構文を使用して、" "
(スペース)をリテラル&
でインデックス(列)$3
と$5
に置き換えます。 |
区切り文字に基づくインデックス位置。
a a|b b|c c|d d|e e
^^^|^^^|^^^|^^^|^^^
$1 |$2 |$3 |$4 |$5
1
の最後に使用されるawk '{...}1'
は何ですか?印刷するのはawkのデフォルトのアクションコントロールです。 詳細を読む
OFS=\|
は、指定された|
区切り文字を使用してフィールドを再び表示または印刷します。
あなたができる
_sed 's/\(|[^| ]*\) */\1\&/4;s//\1\&/2'
_
あなたの例のために。説明:
_|[^| ]*
_は、フィールド区切り文字とその列のすべての非スペースを検索します。 \(\)
でグループ化されているので、後で_\1
_に置き換えてコピーできます。次に、1つ以上の空白が_&
_に置き換えられます。これは、置換文字列でエスケープする必要があります。 _4
_は、これを5番目の列である4番目のオカレンスに適用することを意味します。次に、3番目の列を_2
_で繰り返します。空のパターンを指定してパターンを繰り返す必要はありません。
列にスペースのグループが複数あるか、まったくない場合は、さらに複雑になります。次に、awk
などの別のツールを使用することをお勧めします。
一方、各列に常に空白が1つあることがわかっている場合は、単純な
_sed 's/ /\&/5;s//\&/3'
_
Perl -aF'(\|)' -lne 's/\h/&/ for @F[2*2,2*4]; print @F' input_file
a a|b b|c&c|d d|e&e
f f|g g|h&h|i i|j&j
パイプ|
で現在のレコードを分割し、フィールドに区切り文字も含めます。したがって、3番目と5番目のフィールドは2 * 2および2 * 4フィールドになります。
これらの両方のフィールドで、水平方向の空白\h
をリテラル&
に置き換えます。完了したら、フィールドを印刷します。