列番号がわからないのに、txtファイルの最後の列を削除したいです。どうすればよいですか?
例:
入力:
1223 1234 1323 ... 2222 123 1233 1234 1233 ... 3444 125 0000 5553 3455 ... 2334 222
出力を:
1223 1234 1323 ... 2222 1233 1234 1233 ... 3444 0000 5553 3455 ... 2334
コメント
回答
awk
の場合:
awk "NF{NF-=1};1" <in >out
または:
awk "NF{NF--};1" <in >out
または:
awk "NF{--NF};1" <in >out
これはブードゥーのように見えますが、機能します。これらのawkコマンドにはそれぞれ3つの部分があります。
最初の部分はNF
で、2番目の部分の前提条件です。 NF
は、1行のフィールド数を含む変数です。 AWKでは、「0または空の文字列""
でない場合は真です。したがって、2番目の部分(NF
はデクリメントされます) NF
が0でない場合にのみ発生します。
2番目の部分(NF-=1
NF--
または--NF
)は、NF
変数から1を引くだけです。これにより、最後のフィールドが出力されなくなります。フィールドを変更する(この場合は最後のフィールドを削除する)、awk
再構築$0
、デフォルトでスペースで区切られたすべてのフィールドを連結する。$0
に最後のフィールドが含まれなくなりました。
最後の部分は1
です。これは魔法ではなく、true
を意味する式として使用されているだけです。 awk
式が、関連付けられたアクションなしでtrueと評価された場合、awk
のデフォルトアクションはprint $0
です。 。
コメント
- @JJoao:ああ、ありがとう、
--
を忘れてしまいました。注、現在、POSIXに準拠するには;1
が必要です。 - 最初の本能はforループを使用することですが、これははるかに簡潔で賢い方法です。
- 'デフォルト以外の区切り文字を使用している場合は、'注意してください。'いくつかの変更を加える必要があります。
,
が区切り文字であると仮定すると、次のようになります。awk -F',' 'BEGIN { OFS = FS }; NF { NF -= 1 }; 1' < in > out
- NFのデクリメントの効果は、POSIXでは未定義の動作です。 'を実行しているawkに応じて異なる出力。一部のawkは必要に応じて最後のフィールドを削除し、一部はまったく何もせず、その他は構文エラーなどを報告する可能性があります。
回答
PCREでのgrep
の使用:
$ grep -Po ".*(?=\s+[^\s]+$)" file.txt 1223 1234 1323 ... 2222 1233 1234 1233 ... 3444 0000 5553 3455 ... 2334
GNU
:
$ sed -r "s/(.*)\s+[^\s]+$/\1/" file.txt 1223 1234 1323 ... 2222 1233 1234 1233 ... 3444 0000 5553 3455 ... 2334
コメント
- @raminもちろんです。 。新しい質問として質問していただけますか(これがこのサイトの仕組みです):)
- @ramin何かありますか時間制限や警告はありますか?
- これは標準的な質問ではないと言われています!
- @raminわかりました。管理者に連絡させてください。彼らがお手伝いできるかもしれません。ところで、あなたはあなたの質問に関して古いQAをチェックしましたか?質問がすでに行われ、回答されている可能性があります。
- 'のような非常に基本的な質問をしないでください
Linuxでファイル名の名前を変更するにはどうすればよいですか "。 Googleを使用してください。
回答
Perlの使用:
perl -lane "$,=" ";pop(@F);print(@F)" in
rev
+ cut
の使用:
rev in | cut -d " " -f 2- | rev
回答
GNU sedの使用:
sed -r "s/\s+\S+$//" input.txt
より一般的には、これOSXのBSDsedおよびGNUsedで動作します:
sed "s/[[:space:]]\{1,\}[^[:space:]]\{1,\}$//" input.txt
回答
区切り文字が常に単一の文字である場合(したがって、2つ以上の連続する区切り文字が空のフィールドを指定する場合)、入力ファイルの最初の行だけをhead
、区切り文字を数えることができます( n
区切り文字は、フィールドの数がn+1
)であることを意味し、cut
を使用して1
最初のフィールドからn
番目のフィールド(最後から2番目)まで。例:タブ区切りの入力の場合:
n=$(head -n 1 infile | tr -dc \\t | tr \\t \\n | wc -l) cut -f1-$n infile > outfile
または例: csv ファイルを使用する場合:
n=$(head -n 1 infile | tr -dc , | tr , \\n | wc -l) cut -d, -f1-$n infile > outfile
時間があれば後でいくつかのベンチマークを実行しますが、大量の入力があると思いますこのソリューションは、最初の行で最小限の処理を実行してフィールド数を取得し、このジョブ用に最適化されたcut
を使用するため、正規表現を使用する他のソリューションよりも高速である必要があります。
回答
移植には、次のいずれかを使用できます:
sed "s/[[:space:]]*[^[:space:]]*$//" file awk "{sub(/[[:space:]]*[^[:space:]]*$/,"")}1" file
回答
vimの使用:
vimでファイルを開く
vim <filename>
カーソルが他の場所にある場合に備えて、最初の行に移動します。
gg
“q”という名前のマクロを作成しますqq
、これは現在の行の後ろに移動します$
、次に最後のスペースに戻りますF
(大文字のF、続いてリテラルSPACE)次に、現在の位置から行末まで削除しますD
次の行j
に移動し、q
でマクロの記録を停止します。
qq$F Djq
これで、各行に対して@q
を使用してマクロを繰り返すことができます。
@@
最後のマクロを繰り返すか、さらに簡単に:
99@q
マクロを99回繰り返す。
注:番号は行と正確に一致してはなりません。
回答
同様の問題を抱えているが、フィールド区切り文字が異なる場合は、このawk
メソッドはフィールド区切り文字を正しく保持します:
$ cat file foo.bar.baz baz.bar.foo $ awk -F"." "sub(FS $NF,x)" file foo.bar baz.bar
cut
は仕事のツールのように聞こえます。