このクエリがあります
sed '/./=' abc.txt| sed '/./N; s/\n/, /' >> as.dat
source file has 3 rows like below
a
b
c
次のコマンドを使用すると、次の結果が表示されます。
Output
1 a
2 b
3 c
しかし、私は次のコマンドを出力したいと思います。
Output
a 1
b 2
c 3
答え1
cut
Unixにはandと呼ばれる素晴らしい小さなツールがありますpaste
。このcut
ツールは、列の挿入中に入力から列セットを抽出しますpaste
。私たちはこれを使用します。
私はあなたのパイプラインをあまり気にしません(今はこの答えの終わりを見てください)、熱変換の問題にのみ興味があります。
次のファイルにデータがあるとしますcols.txt
。
$ cat cols.txt
1 a
2 b
3 c
$ paste -d ' ' cols.txt cols.txt
1 a 1 a
2 b 2 b
3 c 3 c
ユーティリティはpaste
通常、列の間にタブ文字を挿入しますが、ここではスペース(-d ' '
)を挿入するように指示します。
paste
次に、with出力から2番目と3番目の列を抽出しますcut
。
$ paste -d ' ' cols.txt cols.txt | cut -d ' ' -f 2,3
a 1
b 2
c 3
cut
私たちは、「フィールド区切り文字」(、それ以外の場合はタブが必要です)としてスペースがあり、フィールド2と3()を-d ' '
持ちたいと言いました。-f 2,3
(残念ながら、元の入力のcut
「」列のみが必要です。2,1
いいえ熱を交換します。 )
したがって、最終的にここでは汚れた正規表現の魔法は必要ありません。
パイプラインに戻ります。スクラップしましょう。各行に行番号を挿入したいようです。nl
( "numberline")という別のUnixツールがあります。
$ nl abc.txt
1 a
2 b
3 c
デフォルトでは、空でない各行の行番号を取得します。前にはパディング用のスペースがあり、タブで元の行と区切ります。空行にも番号を付けますか?
$ nl -b a abc.txt
私が知っている1nl
行の右側に行番号を入れることはできませんが、入力の2つの列を置き換える解決策があるので問題ありません。
$ paste <(nl abc.txt) <(nl abc.txt) | cut -f 2,3
a 1
b 2
c 3
ここでは、区切り文字を指定する必要はありません。nl
各行の先頭にスペースを挿入し、その後に行番号とタブ文字を挿入します。paste
列の間にタブを挿入してcut
タブを切り取ると機能します。
列の間に空白が必要な場合(タブといくつかの空白がある場合)、それをコマンド| tr -s '\t' ' '
に追加します。これは、すべてのタブ文字を空白に変更(「音域」)し、結果の連続する-s
空白を単一の空白に「圧縮」()します。
カンマとスペースが必要な場合は、以下を使用してください| tr '\t ' ', '
。
$ paste <(nl abc.txt) <(nl abc.txt) | cut -f 2,3 | tr -s '\t ' ', '
a, 1
b, 2
c, 3
これは、1行に複数の単語を含むファイルでは機能しますが、タブ文字を含むファイルは失敗します。
$ cat abc.txt # no tabs in this file though
a text there is a
b goes hole in my
c here pants
$ paste <(nl abc.txt) <(nl abc.txt) | cut -f 2,3
a text there is a 1
b goes hole in my 2
c here pants 3
答え2
sed '/./=' | sed '/./{N; s/\(.*\)\n\(.*\)/\2 \1/;}'
しかし、awk
より直接的になります:
awk '/./ {$0 = $0 " " NR}; {print}'
少なくとも1つの文字を含む行にのみ番号を付けるのは奇妙です。これが意図していない場合は、次のように変更できます。
sed = | sed 'N; s/\(.*\)\n\(.*\)/\2 \1/'
awk '{print $0, NR}'
答え3
操作を実行する別の方法は、nl
optionsでコマンドを使用することです-nln
。これはファイルの行に番号を付けます。例えば..
echo -e "a\nb\nc\n" | nl -nln -
生産予定:
1 a
2 b
3 c
今残っているのは、数字を単語の右側に移動するだけです。これは以下をsed
使用して行うことができます。
sed 's/^\([^ \t]*\)[ \t]*\([^ \t].*\)$/\2 \1/g'
それがすることは、行の最初の単語を見つけることです。 (最初の単語を見つけるには、スペースとタブを除く文字のみを含める必要があります。これを使用して行われます。[^ \t]
)スペースと一緒に覚えておいてください。\1
次の行は部分的\2
に置き換えられます\2 \1
。
だから最後のコマンドは
cat filename | nl -nln - | sed 's/^\([^ \t]*\)[ \t]*\([^ \t].*\)$/\2 \1/g'