回答:
以下のためのcut(1)
manページ:
-b、-c、-fのいずれか1つのみを使用してください。各リストは、1つの範囲、またはコンマで区切られた多くの範囲で構成されます。選択された入力は、読み取られたのと同じ順序で書き込まれ、正確に1回だけ書き込まれます。
最初にフィールド1に到達するため、それが出力され、次にフィールド2が出力されます。
awk
代わりに使用:
awk '{ print $2 " " $1}' file.txt
FS
が、オプションでOFS
あり、変数です。例awk -v OFS=";" -F"\t" '{print $2,$1}'
| sed 's/\r//' |
前にパイプすることができますawk
awk '{print $4 "\t" $2 "\t" $6 "\t" $7}' file
また、組み合わせることができるcut
とpaste
:
paste <(cut -f2 file.txt) <(cut -f1 file.txt)
コメント経由:バシズムを回避し、カットのインスタンスを1つ削除することは可能です:
paste file.txt file.txt | cut -f2,3
cut
一意の長さの列セパレーターがある限り、可変長の列でも問題なく機能します。
bash
ISMSをし、1つのインスタンスを削除cut
:実行して paste file.txt file.txt | cut -f2,3
シェルだけを使用して、
while read -r col1 col2
do
echo $col2 $col1
done <"file"
"$col2"
と"$col1"
-シェルのメタ文字またはデータの他のペテンがある可能性があります。
そのためにPerlを使用できます。
perl -ane 'print "$F[1] $F[0]\n"' < file.txt
perlを実行する利点は、(Perlを知っている場合)列を再配置するよりもFではるかに多くの計算を実行できることです。
perl -ae print
同じようcat
に動作します
使用join
:
join -t $'\t' -o 1.2,1.1 file.txt file.txt
ノート:
-t $'\t'
ではGNU join
より直感的な-t '\t'
なし$
(、失敗のcoreutils v8.28およびそれ以前?)。おそらくバグのような回避策$
が必要です。参照:unix join separator char。
join
作業中のファイルが1つしかない場合でも、2つのファイル名が必要です。同じ名前を2回使用するとjoin
、目的のアクションが実行されます。
リソースが少ないシステムでjoin
は、他の回答で使用されている一部のツールよりもフットプリントが小さくなります。
wc -c $(realpath `which cut join sed awk perl`) | head -n -1
43224 /usr/bin/cut
47320 /usr/bin/join
109840 /bin/sed
658072 /usr/bin/gawk
2093624 /usr/bin/perl
非常によく似たものに取り組んでいるだけで、私は専門家ではありませんが、使用したコマンドを共有したいと思いました。私はマルチカラムcsvを持っていましたが、必要なのは4カラムだけであり、それらを並べ替える必要がありました。
ファイルはパイプ '|'でした 区切られていますが、それは交換できます。
LC_ALL=C cut -d$'|' -f1,2,3,8,10 ./file/location.txt | sed -E "s/(.*)\|(.*)\|(.*)\|(.*)\|(.*)/\3\|\5\|\1\|\2\|\4/" > ./newcsv.csv
確かにそれは本当にラフで準備ができていますが、それに合わせて調整することができます!
sedの使用
sedを基本正規表現のネストされたサブ表現とともに使用して、列のコンテンツをキャプチャして並べ替えます。この方法は、この場合のように、列を並べ替えるカットの数が限られている場合に最適です。
基本的な考え方は、検索パターンの興味深い部分を\(
and \)
で囲むことです。これは、置換パターンで再生できます\#
。#
は検索パターン内の部分式の連続した位置を表します。
例えば:
$ echo "foo bar" | sed "s/\(foo\) \(bar\)/\2 \1/"
収量:
bar foo
部分式の外のテキストはスキャンされますが、置換文字列での再生のために保持されません。
質問では固定幅の列については説明しませんでしたが、これは提案されたソリューションの価値ある尺度であるため、ここで説明します。簡単にするために、ファイルがスペースで区切られていると仮定しましょう。ただし、ソリューションは他の区切り文字にも拡張できます。
折りたたみスペース
最も簡単な使用法を説明するために、複数のスペースを単一のスペースに折りたたむことができ、2番目の列の値がEOLで終了している(スペースが埋め込まれていない)と仮定します。
ファイル:
bash-3.2$ cat f
Column1 Column2
str1 1
str2 2
str3 3
bash-3.2$ od -a f
0000000 C o l u m n 1 sp sp sp sp C o l u m
0000020 n 2 nl s t r 1 sp sp sp sp sp sp sp 1 nl
0000040 s t r 2 sp sp sp sp sp sp sp 2 nl s t r
0000060 3 sp sp sp sp sp sp sp 3 nl
0000072
変換:
bash-3.2$ sed "s/\([^ ]*\)[ ]*\([^ ]*\)[ ]*/\2 \1/" f
Column2 Column1
1 str1
2 str2
3 str3
bash-3.2$ sed "s/\([^ ]*\)[ ]*\([^ ]*\)[ ]*/\2 \1/" f | od -a
0000000 C o l u m n 2 sp C o l u m n 1 nl
0000020 1 sp s t r 1 nl 2 sp s t r 2 nl 3 sp
0000040 s t r 3 nl
0000045
列幅を維持する
次に、幅が一定の列を含むファイルにメソッドを拡張し、列の幅を変更できるようにします。
ファイル:
bash-3.2$ cat f2
Column1 Column2
str1 1
str2 2
str3 3
bash-3.2$ od -a f2
0000000 C o l u m n 1 sp sp sp sp C o l u m
0000020 n 2 nl s t r 1 sp sp sp sp sp sp sp 1 sp
0000040 sp sp sp sp sp nl s t r 2 sp sp sp sp sp sp
0000060 sp 2 sp sp sp sp sp sp nl s t r 3 sp sp sp
0000100 sp sp sp sp 3 sp sp sp sp sp sp nl
0000114
変換:
bash-3.2$ sed "s/\([^ ]*\)\([ ]*\) \([^ ]*\)\([ ]*\)/\3\4 \1\2/" f2
Column2 Column1
1 str1
2 str2
3 str3
bash-3.2$ sed "s/\([^ ]*\)\([ ]*\) \([^ ]*\)\([ ]*\)/\3\4 \1\2/" f2 | od -a
0000000 C o l u m n 2 sp C o l u m n 1 sp
0000020 sp sp nl 1 sp sp sp sp sp sp sp s t r 1 sp
0000040 sp sp sp sp sp nl 2 sp sp sp sp sp sp sp s t
0000060 r 2 sp sp sp sp sp sp nl 3 sp sp sp sp sp sp
0000100 sp s t r 3 sp sp sp sp sp sp nl
0000114
最後に、質問の例では長さが等しくない文字列はありませんが、このsed式はこのケースをサポートしています。
ファイル:
bash-3.2$ cat f3
Column1 Column2
str1 1
string2 2
str3 3
変換:
bash-3.2$ sed "s/\([^ ]*\)\([ ]*\) \([^ ]*\)\([ ]*\)/\3\4 \1\2/" f3
Column2 Column1
1 str1
2 string2
3 str3
bash-3.2$ sed "s/\([^ ]*\)\([ ]*\) \([^ ]*\)\([ ]*\)/\3\4 \1\2/" f3 | od -a
0000000 C o l u m n 2 sp C o l u m n 1 sp
0000020 sp sp nl 1 sp sp sp sp sp sp sp s t r 1 sp
0000040 sp sp sp sp sp nl 2 sp sp sp sp sp sp sp s t
0000060 r i n g 2 sp sp sp nl 3 sp sp sp sp sp sp
0000100 sp s t r 3 sp sp sp sp sp sp nl
0000114
シェルの下での他の列並べ替え方法との比較
驚くべきことに、ファイル操作ツールにとって、awkはフィールドからレコードの終わりまで切り取るにはあまり適していません。sedでは、これは正規表現を使用して実行できます。たとえば\(xxx.*$\)
、xxx
は列に一致する式です。
シェルスクリプト内に実装する場合、サブシェルの貼り付けと切り取りを使用するのが難しくなります。コマンドラインから機能するコードは、シェルスクリプト内に取り込まれると解析に失敗します。少なくともこれは私の経験でした(このアプローチに私を駆り立てました)。
cut
この直感的な並べ替えコマンドはサポートされていません。とにかく、もう一つのヒント:あなたが使用することができるawk
の-FS
と-OFS
(のようなカスタム入力および出力フィールドセパレータに使用するオプションを-d
して--output-delimiter
ためにcut
)。