回答:
-F
オプションには引数が必要です。-F,
たとえば。
awk
スクリプトの最後は、残りのパラメーターとともに(スペース文字)で区切る必要があります。
フィールド区切り文字が,
あり、それを保持したい場合、および列の数が一定で11以下の場合、これを試してください:
awk -F, '{print $1,$2,$3,$4,$5,$6,$8,$9,$10,$11,$7}' OFS=, "$file"
command file > newfile && mv newfile file
です。とはいえ、awk
これをサポートするGNUの新しいバージョンは次のとおりgawk -i inplace '{blah blah}' file
です。
mv newfile file
使用することができますcat newfile > file ; rm -f newfile
-これはのinodeとパーミッションを保持しfile
ます。
mktemp
一時ファイル名をスクリプトにハードコーディングするのではなく、使用することをお勧めします。例tf=$(mktemp) ; command file > "$tf" ; cat "$tf" > file ; rm -f "$tf"
より短い解決策は
awk -F',+' -v OFS=, '{$(NF+1)=$7; $7=""; $0=$0; $1=$1}1' file
,+
すべてのawk
バージョンで動作するかどうかは-c
わかりませんが、少なくともGNU awkで動作し、互換性モードでも動作します。
説明:
$(NF+1)=$7
:最初に、行の最後に7番目のフィールドを追加します($12=$7
この場合も可能です)$7=""
:次のステップで7番目のフィールドが消去されます(ただし、周囲の区切り文字はそのままです)$0=$0
、複数のコンマをフィールド区切り文字として処理することにより(-F',+'
ここで+
は1回以上)、レコード全体を再設定し($1=$1
以前の出力フィールドを使用して強制的に行を再構築する)セパレーター(オプションで設定-v OFS=,
)1
入力例:
1,2,3,4,5,6,7,8,9,10,11
出力
1,2,3,4,5,6,8,9,10,11,7
,+
はずです。
all,ball,call,,,fall
→ all,ball,call,fall
)。(2) $(NF+1)=$7
は賢いアプローチです。私見$0 = $0 OFS $7
は、少し明確で、数文字だけ長く、同じことをしているようです。$0 = $0 OFS $7
あなたのコードと同じことをしない状況を考えることができますか?
$0=$0 OFS $7
はおそらくに同じですが$(NF+1)=$7
、一般的にはコードの残りの部分が変更されていないだけです。
あなたはおそらく意味する:
awk -F, -v OFS='' '{print $1,$2,$3,$4,$5,$6,$8,$9,$10,$11,$7}' "$file"
awk
単一引用符が表示されないことを知っていOFS=''
ますか?同様に入力することもできOFS=
ます。それはまったく同じです。
あなたは、特にあなたがawkを使用していたと言っていなかった、とあなたはなかったあなたがが提供するように、インプレース編集を使用したいと言うsed -i
ので、ここで、あるsed -i
変種。通常awk
、列の操作には適していますが、これはsed
自然に任意の数の列を処理するため、私が好むケースの1つです。
MOVECOL=7
N=$((MOVECOL-1))
sed -r -e "s/^(([^,]*,){$N})([^,]*),(.*)/\1\4,\3/" -i test.csv
説明:
-r
拡張された正規表現を選択して、バックスラッシュの多くを回避しますもちろん、これは引用符でコンマを隠す(または、さらに悪いことにエスケープする)ファイルでは機能しませんが、いくつかの深刻なアクロバットがなければ、awkはそれを処理しません。あなたはその問題を持っている場合は、とほうが良いと思いますperl
モジュールText:CSV
またはpython
モジュールcsv
。
いくつかのawk
バリアント(ファイルが変数内にあると仮定$file
)
ここで、すべての列を循環させ、フィールド区切り記号(OFS)を使用して印刷し、行末にレコードターミネーター(ORS)を印刷できます。
awk -F',' -v OFS=, \
'{for(i=1;i<=NF;i++) if (i!=7) printf "%s",$i OFS; \
printf "%s",$7;printf ORS}' "$file"
ここで正規表現とgensub()
関数を使用して
gawk -F',+' -v OFS=, '{$0=gensub(/\s*\S+/,"",7) OFS $7}1' "$file"
殺害 7 番目のフィールドを、行の末尾に、それを印刷。
$0
全記録です $n
n 番目のレコードです NF
現在の行のフィールド数です OFS
出力フィールド区切り文字ORS
出力レコードターミネータ1
これは、awk true
にデフォルト($0
)を出力するように指示するトリックです。更新 ...
ほとんど忘れてしまいますが、7 番目の列に続くすべての列をシフトすることは可能です。
awk -F',' -v OFS=, '{tmp=$7; for(i=7;i<=NF;i++) $i=$(i+1); $NF=tmp}1 ' "$file"
OFS $7
より堅牢です"," $7
。(2)", " $7
OPがコンマの後にスペースを必要としないことを質問が示す限り、それは間違っていると思います。(そして、入力されたデータは、その後、コンマの後にスペースがあった場合は$7
、既にスペースで始まります、そしてあなたは、余分なものを追加することと思います。)
OFS $7
、より堅牢であるだけでなく、より一般的であることに同意します(「速攻は無駄になります」)
^
エラーが発生しましたコマンドの特定の部分を示しています。