フォルダにいくつかのファイルがあり、テキストが次のものではないように、テーブルの形式でfile.txtにその名前を印刷したいと思います。これを達成するためのコマンドはありますか?
dd1.txt dd2.txt dd3.txt dd5.txt
答え1
サブディレクトリに再帰する必要がないと仮定すると、次のようになります。
printf '%s\n' * | paste -d ' ' -s - >other/path/file.txt
これにより、ファイルの1行に現在のディレクトリに表示されているすべてのファイル名が一覧表示されますother/path/file.txt
。
file.txt
現在のディレクトリに書き込むと、そのファイル名が出力の一部になるため、別のディレクトリのファイルに書き込むことを選択しました。明らかに、まず出力ファイル名が自由に利用可能であることを確認してください。
このprintf
ユーティリティは通常シェルに組み込まれているユーティリティなので、何千も*
の名前に拡張できます(注printf
:いいえsh
OpenBSDに組み込まれたユーティリティですがksh
)。ユーティリティは1行に1つのファイル名を生成しますが、ls
場合によっては発生する可能性のある名前自体の形式を妨げません。
このpaste
コマンドは、改行で区切られた名前のリストを取得し、スペースを挟んで1行に表示します。-d
必要に応じて、このオプションを使用して区切り文字を簡単に変更できます。
これにより、改行文字を含むファイル名を正しく処理できず、生成されたリストからスペースを含むファイル名を抽出することもできません。
答え2
$ files=(*)
$ echo "${files[@]}"
dd1.txt dd2.txt dd3.txt dd5.txt
答え3
シェルを使用して現在のディレクトリに隠されていないファイルの名前(語彙順にソートされ、スペース文字で区切られ、改行文字で終わる)を印刷するには、zsh
次のようにします。
print -r - *(N)
または:
echo -E - *(N)
シェルを含むfish
:
set files *; echo -E -- $files
シェルを含むksh93
:
print -r - ~(N)*
シェルを含むyash
:
(set -o nullglob; ECHO_STYLE=raw echo *)
、 、 の場合、およびオプションも有効になっていないbash
場合(一部の展開ではデフォルトで)posix
xpg_echo
bash
(shopt -s nullglob; set -- *; echo -En "$@"$'\n')
または:
POSIXly(Bash(POSIXモードではない)とzsh(POSIXモードでのみ)でも機能します):
set -- [*] *
case "$1$2" in
('[*]*') printf '\n';;
(*)
printf %s "$2"
shift 2
printf ' %s' "$@"
esac
printf '\n'
printf
(現在の作業ディレクトリに多数のファイルがある場合は、組み込みのシェル実装ではこれが失敗する可能性があることに注意してください)。
現在の作業ディレクトリに隠されていないファイルがないか、または読み取れない場合、それらはすべて空白行を印刷します。いずれにせよ、ファイル名に改行文字が含まれていない場合、出力には1行しか含まれません。
標準シェルを使用してこれらの簡単なタスクを実行するのがどれほど難しいかは驚くべきことですが、ここではUnixシェルとユーティリティのいくつかの誤った設計を解決する必要があります。
- この
echo
コマンド(スペースで区切られた引数を出力するコマンド)は、移植するのが最も難しいコマンドの1つであり、標準の実装は簡単に無効にすることができない方法で必要以上の作業を実行します。 - POSIX sh仕様を含む多くのシェルは、不一致の場合に拡張されていないグローブを残します。
- これは
ls
ファイルを一覧表示するコマンドなので、リストを後処理可能な形式で生成する方法はありません。 - この行はできません含むランダムなランダムバイトシーケンス(これはUnixユーティリティはもちろん、Unixだけでなくほとんどのシステムでテキスト行を表すものです)。