次の要素のリストがあります。
a, b, c, 1337, d, e
私が持っていることを望みます:
e, d, 1337, c, b, a
どうすればbashでそれを達成できますか?
次の要素のリストがあります。
a, b, c, 1337, d, e
私が持っていることを望みます:
e, d, 1337, c, b, a
どうすればbashでそれを達成できますか?
あなたはこれを行うことができますawk
:
#!/bin/bash
awk 'BEGIN{FS=",[ ]*"; OFS=", "}
{
for (i=NF; i>0; i--) {
printf "%s", $i;
if (i>1) {
printf "%s", OFS;
}
}
printf "\n"
}'
スクリプトの説明:
FS=",[ ]*";
:フィールド セパレータ(入力の区切り記号)の正規表現は、カンマの後に 0 個以上のスペースが続くものと一致するため、入力は次のいずれかになります。
a, b, c, 1337, d, e
a,b,c,1337,d,e
a, (many spaces) b, c,1337,d, e
OFS=", "
:出力フィールド区切り記号 (出力の区切り記号) は、明示的にコンマの後にスペースが続きます (出力が一貫しているように見えます)。for (i=NF; i>0; i--) { ... }
:現在の行のフィールド数をNF
意味します。ここでは、最後のフィールドから最初のフィールドまで逆方向に反復処理します。if (i>1) { ... }
:OFS
出力の最後のフィールドでない場合にのみ出力しますprintf "\n"
: 新しい行。使用例:
$ ./script_name < input_file > output_file
入力が単純で、列の数が静的である場合は、常にハードコーディングされたawk
ソリューションを使用できます。
awk -F, '{ print $6", "$5", "$4", "$3", "$2", "$1 }'
これは、コンマで区切られた 6 つの列があることを前提としています。「コンマ + スペース」区切り文字がある場合は、の代わりに,
, を使用できます。-F', '
-F,
出力付きの簡単な使用例:
$ echo "a, b, c, 1337, d, e" | awk -F', ' '{ print $6", "$5", "$4", "$3", "$2", "$1 }'
e, d, 1337, c, b, a
入力としてファイルを使用:
awk -F', ' '{ print $6", "$5", "$4", "$3", "$2", "$1 }' your_file
> reversed_columns
;を追加することで、その出力を別のファイルにリダイレクトできます。この場合、「reversed_columns」が新しいファイルの名前です。
このソリューションはあまりエレガントではありませんが、任意の数のフィールドで機能するはずです。
sed 's/, /\n/g' | tac | sed ':a;$!{N;ba};s/\n/, /g'
データをパイプするか、最初の引数の 2 番目の引数としてファイルを指定しますsed
(ただし、ファイル全体をカンマ区切りの 1 行として出力します)。
$ awk -F", " '{for (i=NF;i;i--) printf "%s ",$i; print ""}' < datafile
e d 1337 c b a
次のスクリプトでは、リスト内の要素の数は関係ありません。
IFS=', '; read -a array <<< "a, b, c, 1337, d, e"
let i=${#array[@]}-1;
while [ $i -ge 0 ]; do
echo -n "${array[$i]}, ";
let i--;
done
また、次の perl ワンライナーを使用できます (\n
ただし、最初の要素の後に a が追加されます)。
echo "a, b, c, 1337, d, e" | perl -ne 'foreach(reverse(split(", ",$_))){print "$_, "}'
バッシュ:
echo "a, b, c, 1337, d, e" | (
IFS=", "
while read line; do
set -- $line
for (( i=$#; i > 1; i-- )); do
printf "%s, " "${!i}"
done
echo "$1"
done
)
現在のシェルで IFS 変数を変更しないように、括弧を使用してサブシェルを作成します。