\r\n
ほとんどの回答はファイルの削除に関するものなので、この質問をどのように表現するのかわかりません。
ユニークな問題があります。圧縮ファイルにランダムに番号が付けられており、それをデータベースレコードに正しく関連付けるには、ファイルの内容を一覧表示して確認する必要があります。
このソリューションを使用しています 「Bashスクリプトから1行ずつstdoutをキャプチャする方法」
これは良いスタートです。
一部のコンテンツにはスペースを含む名前があります。次の解決策が見つかりました。 3番目の列を最後の列まで印刷するには?
データベースレコードを更新しようとすると、レコードが^M
パイプラインの結果に挿入されたが列にawk
のみ挿入されることがわかりましたNF
。
この特定の欠陥を解決する方法がわかりません。どこに^M
挿入するのか、最後の列からどのように削除するのかわかりません。
私のコード
この行を削除すると正常に動作します。^M
filename="$(echo "$line" | awk '{if ($3 ~ /^M$/) {sub(/^M$/,"", $3)} printf $3; printf ""}')"
この行は失敗します。
text="$(echo "$line" | awk '{for(i=6;i<NF+1;i++) {if ($i ~ /^M$/) {sub(/^M$/,"", $i)} } printf "%s ", $i; printf ""}')"
単純化されたバージョンは失敗します。
text="$(echo "$line" | awk '{for(i=6;i<NF+1;i++) sub(/^M$/,"", $i) printf "%s ", $i; printf ""}')"
vim
/で使用して作成することはvi
^M
効果がありません。ctrl-V + <return key>
\r\n
私はを使っていてcygwin
、長い間使ってきて、うまく*nix
動作する別のスクリプトを作成しました。何らかの理由でこの特定の実行が出力にawk
追加されることがわかりました。^M
私が見つけたこの問題同様の質問がありましたが、vim
最初からスクリプトを書いたので、Windowsベースのエディタは含まれませんでした。
そのWindowsフォルダをSamba共有としてマウントし、Linux上でスクリプトを実行すると出力が生成されないので、^M
この時点でこれがバグか他の問題なのか疑問に思います。本当に変です。
修正する sub() で REGEX を使用すると文字列が空になるため、CRLF を消去する方法を正しく理解できませんでした。
NF + 1は、i <= NFを使用してCRLFの導入を見つけるための以前の試みの残余です。
答え1
awk
GNUawk
とmawk
busybox(これら3つはLinuxベースのシステムで一般的であり、awk
CygwinのデフォルトはGNUと考えています)を含むいくつかの実装では、入力レコード区切り文字がPOSIXの単一文字ではなく正規表現になる可能性があります。awk
RS
その中で、次のことができます。
awk -v RS='\r\n' '{print $NF}' < your-file.msdos
次のファイルを処理するか、次の操作を行います。
awk -v RS='\r?\n' '{print $NF}' < your-file.msdos-or-unix
\n
区切り文字または区切り文字を使用して\r\n
両方のファイルを処理する機能。
一部のMS-DOSファイルは、区切り文字のない最後の行を好みますが、これはawk
印刷時に出力レコードの区切り文字(ORS
残り\n
)をすべてのレコードに追加するため、出力でもこの問題を修正します。
また、基本フィールド分割に関してawk
実装間の違いを確認することもできます。 POSIXでは、シーケンスに分割する必要があると言います。スペース、先行および末尾を削除します。コンセプトスペースロケールによって異なり、少なくともSPCとTABが含まれます。多くのawk
実装では、ロケールに関係なくSPCとTABのみに制限し、NLも追加します(レコード区切り文字が改行でない場合にのみ関連します)。
busybox
awkにはすべてのASCIIスペースが含まれているのでCR
、FF
。VT
したがって、busyboxでは、awk
フィールドにデフォルトでCRは含まれません。フィールドを空白ではなくシーケンスとして定義することで、awk
GNUを使用して同じ動作を達成できます。gawk -v 'FPAT=[^[:space:]]'
追加の注:
- テキストを処理するシェルループの防止、特にここではすでに使用しているので、
awk
テキスト操作に適したツールの1つです。 echo
任意のデータと一緒に使用しないでください- 最初のパラメータ
printf
は形式であり、そこでランダムなデータを使用したくありません。追加せずに印刷printf "%s", $3
するには、代わりにを使用してください。$3
ORS
printf $3
printf ""
動作しません。効果はありません。改行文字を印刷するには、printf "\n"
またはを使用しますprint ""
(後者はORS
デフォルトで改行文字を印刷します)。
答え2
awk
リテラルの意味は認識されませんが、^M
CRLFパターンとして認識されるため、以下のようにCR文字表現を直接使用できます\r\n
。sub()
また、フィールドに文字が含まれていることを確認して置き換える必要はありません。上記のパターンが見つからない場合、代替関数は何もしません。したがって、最後の列のCRを次に置き換えます。
awk '{ sub("\r", "", $NF); print $NF }'
複数の列を交換する必要がある場合は、$NF
必要な適切な列に切り替えます。
ファイルの最後まですべての列に対してループでこれを行う場合は、次のようにします。
awk '{ for(i=6; i<=NF ; i++) { sub("\r", "", $i); printf "%s ", $i; } }'
また、ファイルには最大のNF
列のみを含めることができ、これは$NF
最後の列の値です。NF
最後の列の値にアクセスするまで実行されるようにループを変更します。