xargsを結合して「ls -1」を引用符で印刷するにはどうすればよいですか?

xargsを結合して「ls -1」を引用符で印刷するにはどうすればよいですか?

ls複数のディレクトリを一覧表示するには、次のコマンドを実行します。フォルダの空き領域を確認してくださいX y

ls -1d 2021*/"X y"/foobar

出力は次のとおりです

'20211121-161518-801/X y/foobar'
'20211128-151513-585/X y/foobar'
'20211130-170001-724/X y/foobar'

lsはここでも引用符を使用しているようです。ただし、この出力を引用符とxargs組み合わせると、継ぎ目が失われます。

ls: Zugriff auf '20211121-161518-801/X' nicht möglich: Datei oder Verzeichnis nicht gefunden
ls: Zugriff auf 'y/foobar' nicht möglich: Datei oder Verzeichnis nicht gefunden

xargs コマンドは次のとおりです。

ls -1d 2021*/"X y"/foobar | xargs ls

結局私はaを使いますが、xargs rm -rfこれはxargs ls単なるテストです。

答え1

Stéphane Chazelasは、「現代」について一般的に見事で深い探求を提供しますが、lsすべてのlsesが同じになるわけではありません。新しいGNUがls登場しても、--zeroどこにも広がるには数十年かかりますが、まだすべてのシステム、特にGNUベースではないシステムでは機能しません。

一般的な合意は、lsこれが人間が消費することであり、実際に他の目的で信頼してはならないということです。

これは以前の管理者の間でかなり常識的ですが、Linuxがニッチ市場を超えて徐々に主流環境と国家化環境に移行するにつれて、新しい管理者と初心者管理者はまだ理解できない(または説明できない)理由で新しい管理者と初心者管理者のみを使用しますしますlsls(あなたの状況でわかるように)深刻な問題になります。これがGNUが何十年にもわたって「急速に」発展してきており、誰にでも選択肢が必要な理由ですlsls

ただし、この問題を即時に、信頼性が高く、安全に解決し、タスクを正しく実行するには、ゼロfind区切りリストジェネレータまたは直接コマンドランチャーとして正しいツールがコマンドです。

findゼロで区切られたリストジェネレータとして使用されます。

find topdir -mindepth 1 [-maxdepth 2] -type d -print0 | xargs -0 -I@ stat @

find直接実行者として使用:

find topdir -mindepth 1 [-maxdepth 2] -type d -exec stat '{}' \;

-mindpeth/を使用すると、ドロップ-maxdepth深度を制御し、find処理-typeするオブジェクトを制御できます。オブジェクト名またはオブジェクトパスも一致させることができます。オブジェクト名は基本的に「インテリジェントな」方法で破損またはエスケープされないため、find恐れなくパイプ(ジェネレータ)またはargvベクトル(ランチャー)の一部としてこれらのアイテムを元のオブジェクトに渡すことができます。

この方法でリストをパイピングするときは、-print0常に名前がゼロで区切られ、他の文字(スペースや改行など)を直接表現できるようにして、読者が混同しないようにする必要があることに注意してください。

答え2

GNU実装には引用スタイルを指定するオプションがlsあります--quoting-styleが、どちらも目的の引用スタイルと互換性がありませんxargs

xargs(1970年代後半にPWB Unixによって導入されました)引用スタイルは、Bourneシェルの前身であるMasheyシェル(PWB Unixに由来)と似ています。

ls --quoting-style=shell-always引用はBourne / POSIXシェルスタイルで行われ、単一引用符自体はバックスラッシュに加えてとして入力されサポートされますが、引用符付き文字列にはバックスラッシュで\'のみxargsエスケープできる改行文字を含めることはできません。'...'"..."

POSIXxargs仕様では、xargs入力は現在のロケールのテキストとして解析されることが予想され、256バイトを超える引数に対する動作も保証されないため、通常は任意のデータを処理するために使用できません。

実際にこれを使用する唯一の信頼できる方法は、通常は非標準として使用したい(GNU)などのいくつかの実装でオプションをxargs使用することです。-0xargs-r

GNU の次のバージョンには、NUL で区切られたファイルを出力するオプションがlsあるので、--zero次のことができます。

ls -t --zero | xargs -r0 printf ' * %s\n'

例えば。

これでできることは、--quoting-style=shell-alwaysパターンを使用してそのリストをシェルに渡してNULで区切られたリストに変換することです。

(
   echo 'files=('
   ls --quoting-style=shell-always -t
   echo '); print -rNC1 -- $files'
) | zsh | xargs -r0 some command

しかし、すでに使用している場合はzsh必ずしもそうではありません。lsファイルメタデータを検索する機能が組み込まれているなど、他の基準に従ってグローバルに並べ替えることもxargsできます(この機能を使用したい唯一の理由)。そして彼自身の順序。zshlsstatlszargs

とにかく、次から

ls -d -- *.txt

*.txt一致するファイルのリストに展開されるシェル。lsただ印刷すればいいのでとても役に立ちません。

print組み込みのNULで区切られたリストを印刷するアイテムにglob拡張を渡すこともできますzsh

print -rNC1 -- *.txt(N)

(ullglob修飾子はここでも使用されるため、Nglobがどのファイルとも一致しない場合は何も印刷しません。)

またはbashシェル(GNUシェルであるため、GNUシステムでまだ使用されている場合もあります):

print0() {
  [ "$#" -eq 0 ] || printf '%s\0' "$@"
}
shopt -s nullglob
print0 *.txt

関連情報