一部の出力の各行から先頭と末尾の空白を削除するにはどうすればよいですか?

出力の各行から先頭と末尾のスペースとタブをすべて削除したい。

次のような簡単なツールはありますかtrim出力をパイプで送ることができますか?

サンプルファイル:

test space at back test space at front TAB at end TAB at front sequence of some space in the middle some empty lines with differing TABS and spaces: test space at both ends 

コメント

  • 改行を削除するための解決策をここで探している人にとって、それは別の問題です。定義上、改行は新しいテキスト行を作成します。したがって、テキスト行に改行を含めることはできません。あなたが尋ねたい質問は、文字列の最初または最後から改行を削除する方法です: stackoverflow.com/questions/369758 、または空白を削除する方法空白だけの行または行: serverfault.com/questions/252921

回答

awk "{$1=$1;print}" 

以下:

awk "{$1=$1};1" 

先頭をトリミングし、末尾のスペースまたはタブ文字 1 および タブのシーケンスをスクイーズします

これは、フィールドの1つに何かを割り当てると、awkがレコード全体を再構築するために機能します。 (printで出力)すべてのフィールドを結合する($1、…、$NFOFS(デフォルトではスペース)

1 (および場合によっては他の空白文字) ■ロケールとawkの実装によって異なります)

コメント

  • セミコロン2番目の例は不要です。使用できるもの:awk '{$1=$1}1'
  • @ Brian、いいえ、;が必要です
  • 興味深い… gawk、mawk、およびOS X ‘ sawkではセミコロンはサポートされていません。 (少なくとも私のバージョン(それぞれ1.2、4.1.1、20070501)の場合)
  • このアプローチについて私が’気に入らないのは、あなたが行内の繰り返しスペースを失います。たとえば、echo -e 'foo \t bar' | awk '{$1=$1};1'
  • echo ' hello ' | xargs

回答

GNU sedを使用している場合、コマンドはそのように凝縮できます:

$ sed "s/^[ \t]*//;s/[ \t]*$//" < file 

上記のコマンドの動作です。

$ echo -e " \t blahblah \t " | sed "s/^[ \t]*//;s/[ \t]*$//" blahblah 

hexdumpを使用して、sedコマンドが目的の文字を正しく削除していることを確認できます。

$ echo -e " \t blahblah \t " | sed "s/^[ \t]*//;s/[ \t]*$//" | hexdump -C 00000000 62 6c 61 68 62 6c 61 68 0a |blahblah.| 00000009 

文字クラス

次のように文字通りセットをリストする代わりに、文字クラス名を使用することもできます。[ \t]

$ sed "s/^[[:blank:]]*//;s/[[:blank:]]*$//" < file 

$ echo -e " \t blahblah \t " | sed "s/^[[:blank:]]*//;s/[[:blank:]]*$//" 

通常のexpreを利用するGNUツールのほとんどssions(regex)は、これらのクラスをサポートします(ここでは、ASCIIベースのシステムの一般的なCロケールで同等のものがあります(そしてそこにのみ))。

 [[:alnum:]] - [A-Za-z0-9] Alphanumeric characters [[:alpha:]] - [A-Za-z] Alphabetic characters [[:blank:]] - [ \t] Space or tab characters only [[:cntrl:]] - [\x00-\x1F\x7F] Control characters [[:digit:]] - [0-9] Numeric characters [[:graph:]] - [!-~] Printable and visible characters [[:lower:]] - [a-z] Lower-case alphabetic characters [[:print:]] - [ -~] Printable (non-Control) characters [[:punct:]] - [!-/:-@[-`{-~] Punctuation characters [[:space:]] - [ \t\v\f\n\r] All whitespace chars [[:upper:]] - [A-Z] Upper-case alphabetic characters [[:xdigit:]] - [0-9a-fA-F] Hexadecimal digit characters 

使用リテラルセットの代わりにこれらは常にスペースの無駄のように見えますが、コードが移植可能であるか、代替の文字セット(国際的なものと考えてください)を処理する必要がある場合は、代わりにクラス名を使用することをお勧めします。 。

参考資料

コメント

  • [[:space:]][ \t]と同等ではないことに注意してください。一般的なケース(ユニコードなど)。 [[:space:]]はおそらくはるかに遅くなります(ユニコードには' 'や)。他のすべてについても同じです。
  • sed 's/^[ \t]*//'は移植性がありません。実際、POSIXでは、一連のスペース、バックスラッシュ、またはt文字を削除する必要があり、’はGNU sedは、POSIXLY_CORRECTが環境内にある場合にも機能します。
  • 改行文字をトリミングしたい場合はどうすればよいですか? ‘ \ n \ nテキスト\ n \ n ‘
  • sedソリューションが不足しているので気に入っていますawkソリューションのように他の副作用。最初のバリエーションは、OSX jsutでbashで試したときに機能しませんが、文字クラスバージョンは機能します:sed 's/^[[:blank:]]*//;s/[[:blank:]]*$//'
  • @EugeneBiryukovコメントを参照してください元の投稿

回答

引数のないxargsがそれを行います。

例:

trimmed_string=$(echo "no_trimmed_string" | xargs) 

コメント

  • これにより、内の複数のスペースも縮小されます質問で要求されなかった行
  • @ roaima-trueですが、受け入れられた回答はスペースも圧縮します(質問では要求されませんでした)。ここでの本当の問題は、入力に円記号と一重引用符が含まれている場合、xargsの配信に失敗することだと思います。
  • @don_crissti、’とはいえ、受け入れられた回答が質問に正しく答えることを意味するわけではありません。ただし、この場合、ここでは’警告としてフラグが立てられていませんでしたが、受け入れられた回答ではフラグが立てられていました。 ‘将来の読者との関連性が’ある場合に備えて、事実を強調したいと思います。
  • また一重引用符、二重引用符、円記号で区切ります。また、1つ以上のecho呼び出しを実行します。一部のエコー実装は、オプションやバックスラッシュも処理します…これは単一行入力に対してのみ機能します。

回答

承認された回答のStéphaneChazelasで提案されているように、
スクリプトを作成できるようになりました/usr/local/bin/trim

#!/bin/bash awk "{$1=$1};1" 

そしてそのファイルに実行可能権限を付与します:

chmod +x /usr/local/bin/trim 

これで、すべての出力をtrimに渡すことができます。例:

cat file | trim 

(以下のコメントの場合:以前にこれを使用しました:while read i; do echo "$i"; done
これも正常に機能しますが、パフォーマンスは低下します)

コメント

  • ファイルが巨大であるか、バックスラッシュが含まれている場合は幸運を祈ります。
  • @don_crissti:もう少しコメントしていただけますか?巨大なファイルにより適しています。ファイルにバックスラッシュが含まれている場合、どうすればソリューションを変更できますか?
  • ‘バックスラッシュを保持するには、while read -r lineを使用する必要があり、それでもを使用する必要があります… 。巨大なファイル/速度に関しては、本当に、あなたは最悪の解決策を選びました。 ‘そこに’もっと悪いことはないと思います。 テキストの悪い習慣を処理するためにシェルループを使用するのはなぜですか?速度ベンチマークへのリンクを追加した最後の回答へのコメントを含めて、回答を参照してください。ここでのsedの回答は完全に優れたIMOであり、readよりもはるかに優れています。
  • エイリアスを追加することもできます。 / etc / profile(または〜/ .bashrcまたは〜/ .zshrcなど)エイリアスtrim = ” awk ‘ { \ $ 1 = \ $ 1}; 1 ‘ ”
  • bash#! /usr/bin/awk -f {$1=$1};1にすることができます。 (ただし、=文字を含むファイル名に注意してください)

回答

行を変数として格納する場合は、bashを使用してジョブを実行できます。

文字列から先頭の空白を削除します:

shopt -s extglob echo ${text##+([[:space:]])} 

文字列から末尾の空白を削除する:

shopt -s extglob echo ${text%%+([[:space:]])} 

文字列からすべての空白を削除する:

echo ${text//[[:space:]]} 

コメント

  • 文字列からすべての空白を削除することは、(問題のように)先頭と末尾の両方のスペースを削除することと同じではありません。
  • 最善の解決策-bashビルトインのみが必要で、外部プロセスフォークは必要ありません。
  • いいですね。スクリプトは、’外部プログラム(awkやsedなど)を取り込む必要がない場合、非常に高速に実行されます。これは、”モダン”(93u +)バージョンのkshでも機能します。

回答

sed -e "s/^[[:space:]]*//" -e "s/[[:space:]]*$//" 

シェル変数に行を読み込む場合は、readは、特に指示がない限り、すでに実行しています。

コメント

  • +1 for read。したがって、読み取り中にパイプを使用すると、機能します:cat file | while read i; do echo $i; done
  • @ruboこの例では、引用符で囲まれていない変数もシェルによって再処理されます。echo "$i"を使用して、read

回答

「パイプ」ツールを使用して、特定の行からすべての先頭と末尾のスペースを削除するために、3つの異なるものを識別できます。完全に同等ではない方法これらの違いは、入力行の単語間のスペースに関係します。予想されるbに応じて行動、あなたはあなたの選択をするでしょう。

違いを説明するために、次のダミー入力行について考えてみましょう。

" \t A \tB\tC \t " 

tr

$ echo -e " \t A \tB\tC \t " | tr -d "[:blank:]" ABC 

trは本当に単純なコマンドです。この場合、スペースまたは集計文字はすべて削除されます。

awk

$ echo -e " \t A \tB\tC \t " | awk "{$1=$1};1" A B C 

awk先頭と末尾のスペースを削除し、単語間のスペースごとに1つのスペースに絞り込みます。

sed

$ echo -e " \t A \tB\tC \t " | sed "s/^[ \t]*//;s/[ \t]*$//" A B C 

この場合、sedは、単語間のスペースに触れずに先頭と末尾のスペースを削除します。

備考:

1行に1単語の場合、trが機能します。

コメント

  • ただし、末尾/先頭の改行をトリミングするものはありません
  • +1して、(場合によっては予期しない)出力を含むソリューションのリストを表示します。
  • @ user61382これはかなり遅いですが、元の投稿に対する私のコメントを参照してください。
  • @highmaintenance:コマンドblank:]の代わりに[:space:]を使用してくださいdiv id = “dd2bc4a516”>

、例:... | tr -d [:space:]、改行も削除します。 (man trを参照)

回答

sedはそのための優れたツール:

 # substitute ("s/") sed "s/^[[:blank:]]*//; # parts of lines that start ("^") with a space/tab s/[[:blank:]]*$//" # or end ("$") with a space/tab # with nothing (/) 

テキスト内のパイプのいずれかである場合に使用できます。例:

<file sed -e "s/^[[... 

または、sedがGNUの場合は、「インライン」で操作します。

sed -i "s/..." file 

ただし、この方法でソースを変更すると、正しく機能しない場合(または機能する場合でも!)に回復できない可能性があるため、「危険」です。最初にバックアップしてください(または-i.bakこれには、一部のBSD sedに移植できるという利点もあります!

回答

一目で理解できる回答:

#!/usr/bin/env python3 import sys for line in sys.stdin: print(line.strip()) 

ボーナス:

任意の文字を使用して、必要に応じて.lstrip()または.rstrip()をトリミングまたは使用します。

rubo77 “saのようにnswer 、スクリプト/usr/local/bin/trimとして保存し、chmod +xで権限を付与します。

回答

トリミングしようとしている文字列が短く、連続的/連続的である場合は、パラメータとして渡すだけです。任意のbash関数へ:

 trim(){ echo $@ } a=" some random string " echo ">>`trim $a`<<" Output >>some random string<< 

回答

このシェル関数はawk

awkcliptor(){ awk -e "BEGIN{ RS="^$" } {gsub(/^[\n\t ]*|[\n\t ]*$/,"");print ;exit}" "$1" ; } 

BEGIN{ RS="^$" }
最初にset record
セパレーターの解析を開始する前にnoneつまり、入力全体を
単一のレコードとして扱います

gsub(this,that)
この正規表現をその文字列に置き換えます

/^[\n\t ]*|[\n\t ]*$/
その文字列の
は、改行前のスペースとタブクラスをキャッチするか、
改行スペースとタブクラスを投稿して、
空の文字列に置き換えます

print;exit:次に印刷して終了します

"$1"
そして関数の最初の引数をに渡します
awkによる処理

使用方法:
上記のコードをコピーし、シェルに貼り付けてから、
defineに入力します。関数。
次に、awkcliptorをコマンドとして使用し、最初の引数を入力ファイルとして使用できます。

使用例:

echo " ggggg " > a_file awkcliptor a_file 

出力:

ggggg 

または

echo -e "\n ggggg \n\n "|awkcliptor 

出力:

ggggg 

コメント

  • 違いをawk '{$1=$1};1'だけに説明していただけますか?

回答

脳内にあいまいなsed構文を覚えるのに十分なスペースがない場合は、文字列を逆にしてください。 、スペースの区切り文字で最初のフィールドを切り取り、もう一度元に戻します。

cat file | rev | cut -d" " -f1 | rev 

コメント

  • これは、各行の先頭にスペースが1つしかなく、1行に単語が1つしかない場合にのみ機能します。

回答

trimpy () { python3 -c "import sys for line in sys.stdin: print(line.strip())" } trimsed () { gsed -e "s/^[[:space:]]*//" -e "s/[[:space:]]*$//" } trimzsh () { local out="$(</dev/stdin)" [[ "$out" =~ "^\s*(.*\S)\s*$" ]] && out="$match[1]" || out="" print -nr -- "$out" } # example usage echo " hi " | trimpy 

ボーナス:str.strip([chars])を任意の文字に置き換えて、トリミングまたはまたは.rstrip()

回答

translateコマンドは機能します

cat file | tr -d [:blank:] 

コメント

  • このコマンドはを削除するため、正しくありません先頭/末尾の空白だけでなく、ファイルのすべての スペース。
  • @BrianRedbeard正解です。これは、スペースのないモノリシック文字列に対しては依然として有用な答えです。

回答

bashの例:

alias trim="awk "{\$1=\$1};1"" 

使用法:

echo -e " hello\t\tkitty " | trim | hexdump -C 

結果:

00000000 68 65 6c 6c 6f 20 6b 69 74 74 79 0a |hello kitty.| 0000000c 

コメント

  • awk '{$1=$1};1'の回答はずっと前に出されました。 それからエイリアスを作成するというアイデアは、ほぼ同じくらい前のコメントで提案されました。 はい、他の人のコメントを受け取って回答に変えることは許可されています。 しかし、そうする場合は、あなたの前にアイデアを投稿した人々にクレジットを与える必要があります。 そして、これは受け入れられた答えの非常に些細な拡張であるため、気にする価値はありません。
  • アイデアはエイリアスを作成することでした。 ‘以前にその回答を見たことがありません。
  • そしてスタックから2番目のもの:”フィードバックをありがとうございます。 レピュテーションが15未満の投票は記録されますが、公開されている投稿スコアは変更されません。”

コメントを残す

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