私は多数のエントリを含むtest.txtファイルを持っています。以下はその例です。
Afghanistan
Albania
Algeria
Andorra
Angola
Antigua and Barbuda
Argentina
Armenia
Australia
Austria
Azerbaijan
The Bahamas
Bahrain
Bangladesh
Barbados
Belarus
Belgium
Belize
Benin
Bhutan
Bolivia
Bosnia and Herzegovina
Botswana
Brazil
Brunei
Bulgaria
Burkina Faso
Burundi
Cabo Verde
Cambodia
Cameroon
Canada
Central African Republic
Chad
Chile
China
Colombia
Comoros
cat test.txt | tr '\n' ','
新しい行をカンマ区切りリストに変換するために使用できます。
ただし、以下に示すように、それぞれ6つのセットで別々のリストを作成するコマンドが必要です。
Afghanistan,Albania,Algeria,Andorra,Angola,Antigua and Barbuda
Argentina,Armenia,Australia,Austria,Azerbaijan,The Bahamas
Bahrain,Bangladesh,Barbados,Belarus,Belgium,Belize
and so on ...
Centos bashシェルでこれを行うにはどうすればよいですか?
答え1
$ paste -d, - - - - - - <file
Afghanistan,Albania,Algeria,Andorra,Angola,Antigua and Barbuda
Argentina,Armenia,Australia,Austria,Azerbaijan,The Bahamas
Bahrain,Bangladesh,Barbados,Belarus,Belgium,Belize
Benin,Bhutan,Bolivia,Bosnia and Herzegovina,Botswana,Brazil
Brunei,Bulgaria,Burkina Faso,Burundi,Cabo Verde,Cambodia
Cameroon,Canada,Central African Republic,Chad,Chile,China
Colombia,Comoros,,,,
ここで、コマンドpaste
はコンマで区切られた出力の6つの列を生成するために使用されます。
この例では、最後の行の最後の数列を埋めるのに十分なデータがないため、列は空です。これを削除するには、sed '$s/,*$//'
最後の行のすべての末尾のコンマが削除される結果をパイプします。
$ paste -d, - - - - - - <file | sed '$s/,*$//'
Afghanistan,Albania,Algeria,Andorra,Angola,Antigua and Barbuda
Argentina,Armenia,Australia,Austria,Azerbaijan,The Bahamas
Bahrain,Bangladesh,Barbados,Belarus,Belgium,Belize
Benin,Bhutan,Bolivia,Bosnia and Herzegovina,Botswana,Brazil
Brunei,Bulgaria,Burkina Faso,Burundi,Cabo Verde,Cambodia
Cameroon,Canada,Central African Republic,Chad,Chile,China
Colombia,Comoros
答え2
mapfile -t data < test.txt;
printf '%s,%s,%s,%s,%s,%s\n' "${data[@]}";
オフセットが大きく、実行可能なソリューションが必要な場合はawkを使用し、そうでない場合は純粋なシェルが必要な場合は少し屋根が必要になることがあります!
f () {
offset=$1;
infile="$2";
mapfile -t data < "$infile";
while ((${#data[@]}));do
line="$(printf '%s,' "${data[@]:0:offset}")";
data=("${data[@]:offset}");
echo "${line%,*}";
done
}
f 5 test.txt
答え3
必要な数の列に対して、次の操作を行います。
awk -v col=6 '{printf "%s%s", (NR>1) ? (NR-1) % col ? "," : RS : "", $0}
END{if (NR) print ""}' < your-file
使用してくださいpr
(例の入力にpr
いくつかの実装で認識されている特別なシーケンスの1つが含まれていないとします。
pr -t -a -s, -6 < your-file
GNUを使用すると(または非標準)pr
を使用しない限り、36列(72列の半分、デフォルトのページ幅)を超えることはできませんが、一部の切り捨て/パディングが発生することがわかります。この問題を解決するためにGNU拡張も使用できますが、これがどのような他の副作用をもたらすかは誰が知っていますか?-w
-W
-J
GNUの45列の場合pr
:
pr -Jtas, -w90 -45
(YMMV他のpr
実装と同様に、このpr
コマンドも非常に混乱しています。)
答え4
awkを使用できます。
$ awk 'BEGIN{i=1;} { a[i]=a[i]","$0;if(NR%6==0){sub(",","",a[i]);print a[i];i++;} } END {if(a[i]){sub(",","",a[i]);print a[i]}}' file
Afghanistan,Albania,Algeria,Andorra,Angola,Antigua and Barbuda
Argentina,Armenia,Australia,Austria,Azerbaijan,The Bahamas
Bahrain,Bangladesh,Barbados,Belarus,Belgium,Belize
Benin,Bhutan,Bolivia,Bosnia and Herzegovina,Botswana,Brazil
Brunei,Bulgaria,Burkina Faso,Burundi,Cabo Verde,Cambodia
Cameroon,Canada,Central African Republic,Chad,Chile,China
Colombia,Comoros
またはPerlの1行を使用してください。
perl -a -F'\n' -00 -ne ' map { (($_ + 1)%6 == 0) ? print $F[$_]."\n" : print $F[$_].","; } ( 0 .. @F-1); print "\n" if eof' file