誰でも私を助けることができますか?多くのファイルを作成しようとしていますが、echoを使用してファイルに書き込もうとすると、次のようにスペースと一重引用符が追加されます。
' (here is the space) file.tmp'
' file1.tmp'
' file3.tmp'
コードは次のとおりです。
cat limpio.tmp | while read line; do
srcip=$(echo $line | awk -F"," '{print $1}')
destip=$(echo $line | awk -F"," '{print $2}')
port=$(echo $line | awk -F"," '{print $NF}')
echo "${srcip}" >> "$destip.tmp"
done
問題は、catを使用してコンテンツを繰り返し表示しようとしたときに発生しますが、空白のため機能しません。
非常にありがとう
ベストアンサー1
このecho
ユーティリティはスペースを挿入しますが、出力時の引数間の区切り文字としてのみ使用されます。
$ echo 1 2 3 4 'A B C'
1 2 3 4 A B C
B
との間のスペースはC
同じパラメータの一部であるため保持されますecho
。
echo
それではこれではありません。入れる空白がありますが、データには既に空白が含まれています。
私はあなたが見る一重引用符がls
システム出力の一部であると仮定します(参照「ls」が突然空白を一重引用符で囲むのはなぜですか?) またはシェル実行中のトレース出力の一部である可能性がありますset -x
(参照bashがコマンドを実行する前に引用符を持たない失敗したパス名拡張子に一重引用符を追加するのはなぜですか?)。つまり、実際にはファイル名の一部ではなく、一部のツールが名前をレンダリングする方法にすぎません。
たとえば、入力内容が次のようになるとします。
174.18.418.83, 10.404.401.94, 53144
174.18.418.83, 10.404.401.94, 53144
174.18.418.83, 10.404.401.94, 53144
カンマ区切り文字の後にスペースがあることがわかります。カンマを区切り文字として上記のファイルから 2 番目のフィールドを読み取ると、フィールドの先頭にスペースが残り、そのデータをファイル名として使用すると、ファイル名がスペースで始まります。
(注意深い読者であれば、問題のコードline
が引用符で囲まれていない変数を使用していることがわかります。これは、シェルが変数の値を空白に分割し、などの別々のパラメータとしてecho
表示することを意味します)。174.18.418.83,
10.404.401.94,
53144
それは真実です。ある意味、echo
削除するスペースを挿入しますが、データにスペース/タブがない場合はこれを行いません。また、見ることができますいつ二重引用符が必要ですか?)
回避策は、カンマと次の空白文字を区切り文字として使用することですawk
。
awk -F ',[[:blank:]]*' '{ print $2 }'
この式は、,[[:blank:]]*
カンマの後に複数の空白文字が続くものと一致します。 「空白」文字は空白またはタブ文字です。, *
リテラルスペースがあることがわかっている場合は、これを(「カンマ、スペース、アスタリスク」)に変更できます。
今電話を避けるawk
サム入力ファイルの各行の時間を入力します。
print
の文は、ファイル名の後にファイル名をawk
使用してシェルから出力をリダイレクトするのとほぼ同じ方法で「リダイレクト」できます。>
使用するファイル名は、2番目のフィールドに.tmp
追加された名前です。
これは、質問のループ全体を単一のコマンドに置き換えることができることを意味しますawk
。
awk -F ',[[:blank:]]*' '{ print $1 > ($2 ".tmp") }' limpio.tmp
式は、2番目のフィールドの内容を追加した結果の文字列として評価されます($2 ".tmp")
。.tmp
>
withを使用すると、print
出力ファイルが最初のファイルで作成または切り捨てられ(空になり)、同じ名前の後にのみ新しいprint
行が追加されます。代わりにをprint
使用すると、最初の項目はファイルを切り捨てるのではなくファイルに追加されます。>>
>
print
これには完全性チェックが組み込まれていないため、2番目の列に入力した内容によっては、上記の内容によって書き込みアクセス権があるシステムの重要なファイルが破損する可能性があります。
GNUを使用する場合awk
、これがあなたがしなければならないことです。ただし、他のファイルを使用しawk
て多数のファイルを作成する必要がある場合は、close()
ファイルを処理するときにこれらのファイルを手動で呼び出す必要があるかもしれません。そうしないと、使用可能なファイル記述子が不足する可能性があります。
awk -F ',[[:blank:]]*' '{ fn = $2 ".tmp"; print $1 >>fn; close(fn) }' limpio.tmp
ここでは、出力ファイル名を変数に保存しますfn
。次に、出力をファイルに追加してからファイルを閉じます。これにより、使用可能なファイル記述子をすべて使用する必要がなくなりますが、コマンドを再実行する必要がある場合は、出力ファイルを常に使用して手動でクリーンアップ>>
(削除)する必要があります。print
awk
GNUはawk
開いているファイルディスクリプタの数を追跡し、必要に応じて閉じ始めます(後でファイルにデータを書き込む必要がある場合は、追加するためにファイルを再度開きます)。
また見なさい: