web-dev-qa-db-ja.com

エコー* | xargs -n1 echo、行ごとの一覧表示のより短く、よりエレガントな方法はありますか?

lsを実行すると、出力は列に表示されますが、出力は行ごとに1列、行ごとに1エントリのみである必要があります。

だから私が思いつくことができる唯一の方法は:

echo * | xargs -n1 echo

これはそれを達成するための標準的な方法ですか、それともこの悪いスタイルですか?

2
sharkant

これは悪いことです。すべての理由から、プレーンxargsは悪いことです。つまり、空白またはバックスラッシュを含むファイル名で壊れます。

$ touch "foo bar"
$ echo * | xargs -n1 echo
foo
bar

さらに、すべてのファイルに対して(外部の)echoコマンドのコピーを実行します。

ほとんどのシェルでは、printf "%s\n" *を使用してリストを取得できます。またはls -1

ただし、問題は、ファイルのリストをどのように処理するかです。それらを見るか、スクリプトで使用しますか?後者の場合、おそらく使用する方が良いでしょう

for f in * ; do something with "$f" ; done

またはfind ... -exec somecmd {} +のバリアント

3
ilkkachu

Xargsに関する一般的なアドバイスは、xargsを使用しないことです。その入力形式は、一般的なツールではサポートされていません。

Xargsの使用法の次のレベルは、ヌルで区切られた入力でxargs -0を使用することです。しかし、あなたの場合、xargsはとにかく無意味です。

ディレクトリ内のファイルを一覧表示する場合は、lsを使用できます。 1行に1つのファイルがあることを確認するには、ls -1を使用します。 lsコマンドは、出力がパイプまたはファイルに送られるとき、常に1行に1つのファイルを置きます。出力がターミナルの場合、プレーンlsは列内のファイル名を整列しますが、ls -1は整列しません。

単語のリストがあり、それらを1行に1つずつ印刷する場合は、printf '%s\n'を使用できます。これはechoと同様に機能しますが、スペースの代わりに各要素の後に改行を出力し、バックスラッシュやダッシュの処理の危険性がない点が異なります。

printf '%s\n' *          # prints the names of the files in the current directory
printf '%s\n' "$@"       # prints the positional arguments
printf '%s\n' "${a[@]}"  # prints the element of the array `a`

ファイル名に特殊文字が含まれていると、意図したとおりに動作しません。

$ touch 'name
with newline' 'other name\nwith newline'
$ echo * | xargs -n1 echo
name
with
newline
other
name
with
newline

ファイルを一覧表示するだけの場合は、ls -1があります。それ以外の場合は、-execフラグを指定したfindを使用します。

3
ctx