7

次の要素のリストがあります。

a, b, c, 1337, d, e

私が持っていることを望みます:

e, d, 1337, c, b, a

どうすればbashでそれを達成できますか?

4

6 に答える 6

5

あなたはこれを行うことができます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
于 2012-11-13T19:13:40.570 に答える
2

入力が単純​​で、列の数が静的である場合は、常にハードコーディングされた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」が新しいファイルの名前です。

于 2012-11-13T19:12:22.417 に答える
2

このソリューションはあまりエレガントではありませんが、任意の数のフィールドで機能するはずです。

sed 's/, /\n/g' | tac | sed ':a;$!{N;ba};s/\n/, /g'

データをパイプするか、最初の引数の 2 番目の引数としてファイルを指定しますsed(ただし、ファイル全体をカンマ区切りの 1 行として出力します)。

于 2012-11-13T19:14:42.983 に答える
2
$ awk -F", " '{for (i=NF;i;i--) printf "%s ",$i; print ""}' < datafile
e d 1337 c b a 
于 2012-11-13T19:22:35.630 に答える
1

次のスクリプトでは、リスト内の要素の数は関係ありません。

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 "$_, "}'
于 2012-11-13T19:21:42.177 に答える
1

バッシュ:

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 変数を変更しないように、括弧を使用してサブシェルを作成します。

于 2012-11-13T19:48:56.087 に答える