Linuxでファイルの最後の列を削除する方法

列番号がわからないのに、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 

コメント

  • これを行う方法はたくさんあります。例を追加して期待される出力..
  • @heemaylokやりました
  • ありがとうございます。列タブが分離されていますか、それともスペースが分離されていますか?
  • @heemaylスペースはデリミネーターです
  • cutは仕事のツールのように聞こえます。

回答

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 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です