ディレクトリ内のすべてのファイルのすべてのファイル名を.txt
ファイルに出力したいと思います。
3つのファイルを含むディレクトリがあるとしましょう。
file1.txt
file2.txt
file3.txt
ls > output.txt
を使ってみました。
問題は、output.txt
を開くと、次のリストが見つかることです。
file1.txt
file2.txt
file3.txt
output.txt
出力をリダイレクトしているファイルの名前を印刷しないようにする方法はありますか?または、1つを除いてディレクトリ内のファイルのすべてのファイル名を出力できるコマンドがありますか?
printf '%s\n' * > output.txt
これは、既存のoutput.txt
ファイルがないことを前提としていることに注意してください。存在する場合は、最初に削除してください。
printf '%s\n' *
は globbing(filename Expansion) を使用して、現在のディレクトリにあるすべてのファイルとサブディレクトリの名前を1行ずつ確実に出力します。
グロビングが発生するbeforeoutput.txt
は、出力リダイレクト> output.txt
を介して作成されます(コマンドがexecuted、これは問題を説明します)、そのため、その名前はnotです。
グロビングは、ls
の使用も回避します。スクリプトでの使用は 一般的には推奨されません です。
一般に、ls
の出力を解析することは、特に長期間にわたって良好な状態を維持する必要がある本番環境品質のスクリプトを記述している場合は好ましくありません。理由を確認するには、このページを参照してください。 ls出力を解析しないでください
あなたの例では、シェルはls
を実行する前に(output.txtへの)リダイレクトを調整するため、output.txt
はls > output.txt
の出力の一部です。
ケースに適切な動作をさせる最も簡単な方法は次のとおりです。
ls file*txt > output.txt # as long as you are looking for files named that way
または、出力を隠しファイル(または他のディレクトリにある通常のファイル)に保存してから、最終的な場所に移動します。
ls > .output.txt && mv .output.txt output.txt
より一般的な解決策は、grep -v
を使用することです。
ls | grep -vFx output.txt > output.txt
または、配列を使用できます。
files=( "$(ls)" )
printf '%s\n' "${files[@]}" > output.txt
ls
には無視オプションがあり、find
コマンドも使用できます。
ls
を無視オプションとともに使用する
ls -I "output.txt" > output.txt
ls --ignore "output.txt" > output.txt
-I, --ignore
は同じです。このオプションは、manページのように、シェルパターンに一致する暗黙のエントリを一覧表示しないことを示します。
find
の使用
find \! -name "output.txt" > output.txt
find
の-name
オプションは、名前がパターンに一致するファイル/ディレクトリを検索します。! -name
は、名前がパターンに一致するものを除外します。
find \! -name "output.txt" -printf '%P\n' > output.txt
%Pはパスを取り除き、名前のみを指定します。
ファイル名について何も想定しない最も安全な方法は、bash配列(メモリ内)または一時ファイルを使用することです。一時ファイルはメモリを必要としないため、さらに安全になる場合があります。何かのようなもの:
#!/bin/bash
tmp=$(tempfile)
ls > $tmp
mv $tmp output.txt
ls
およびawk
コマンドを使用すると、正しい出力を取得できます。
ls -ltr | awk '/txt/ {print $9}' > output.txt
これはファイル名のみを出力します。