
現在のディレクトリですべてのファイルを見つけて内容を処理する前に、アルファベット順にソートして各ファイルの最初の3文字を抽出したいと思います。これにより、他のファイルにリダイレクトできる文が生成されます。私はこれを試しました:
find . -type f -exec basename {} \; | sort | xargs head -c 3
しかし、私は次のようになります。
ヘッド:読み取り用に 'filenamehere'を開くことができません。そのファイルやディレクトリはありません。
すべてのファイルに対して最初の3文字を抽出しようとしています。まず、ソートせずにこれを実行できました。
答え1
編集する: 初めて:
find -type f -exec grep -I -q . {} \; -exec sh -c 'echo -e "$(basename "$0") {}"' {} \; | sort | cut -d ' ' -f2 | xargs sed -Ee 's/(^.{3})(.*)/\1/g'
grep -I -q . {} \;
画像などのバイナリファイルは検索されず、すべてのテキストファイルのみが検索されます。
第二:
私の基本的なアイデアは、キーが基本名と同じで、値が最初の3文字であるハッシュ関数を作成することです。
#!/bin/bash
touch file_s
echo 'declare -A map' > file_s
find . ! -name file_s ! -name sort_map -type f -exec grep -I -q . {} \; \
-exec sh -c 'i="$(basename "$0")";echo "map["$i"]=$(head -n 1 "$0"|cut -c
1-3)" >> file_s;' {} \; | sort | while read -r line
do
source file_s
echo -e ${map["$line"]}
done
このコードを書く必要があるスクリプトの名前は一時的sort_map
ですfile_s
。文書。したがって、findコマンドにこれら2つのファイルを含めないでください。grep -I -q . {} \;
grepファイルをバイナリファイルではなくテキストファイルとしてのみ作成します。
2番目の-exec
コマンドは次のとおりです。
i="$(basename "$0")";
デフォルト名を取得し、変数iに書き込みます。
echo "map["$i"]=$(head -n 1 "$0"|cut -c 1-3)" >> file_s;
ハッシュ関数とその値を一時ファイルに書き込みますfile_s
。
sort
ファイル名がソートされます。
while read -r line
do
source file_s
echo -e ${map["$line"]}
done
ファイルを1行ずつ読み込み、インポートしますfile_s
。これで最初の3文字が印刷されます。
head はファイル名ではなくファイルの内容を印刷するため、head は使用できません。
あなたはそれを使用することができます:
find . -type f -exec basename {} \; | sort | cut -c 1-3
b
または、オプションを代わりに使用できますが、c
すべての文字が1バイトであると仮定します。
find . -type f -exec basename {} \; | sort | cut -b 1-3
最初の3文字を取得します。
あなたはそれを使用することができます:
find . -type f -exec basename {} \; | sort | sed -Ee 's/(^.{3})(.*)/\1/g'
ファイルを並べ替え、最初の3文字を一致させてのみ印刷します。
メモ:これらのコマンドはすべて、スペースとタブを1文字として扱います。
答え2
basename
NETのすべてのファイルに対して実行しないでくださいfind
。見つかったすべてのファイルに対してシェルを実行するのは膨大なリソースの無駄です。
find
(GNUバージョンを想定すると、他のバージョンでもサポートできます。)ファイル名だけでなく、サイズ、所有権、権限などを含むファイルに関する情報を出力する方法を示すフォーマット文字列を使用するfind
ディレクティブがあります。-printf
1つの形式は、使用している形式%f
であるファイル名からすべての先行ディレクトリを削除することです。basename
だからあなたは使用することができます
find -type f -printf '%f\n'
\n
各ファイル名が1行に表示されるように改行を追加する必要があります。
もう1つの利点は、この方法で印刷する文字数に制限を追加できることです。最大3文字のファイル名を印刷するには、次のようにします。
find -type f -printf '%.3f\n'
今sort
ミックスに追加します。
find -type f -printf '%.3f\n' | sort
あなたはあなたの解決策を持っています。
編集:ファイルをソートしてからその内容の最初の3文字を出力する必要があるように見えるので、コマンドは次のようになります。
find -type f -printf '%f\t%p\n' | sort | cut -f2 | xargs head -n 1 | cut -c1-3
これはフォーマット文字列を使用して最初にデフォルトのファイル名のみを表示し、次にタブ、最後にフルパスを表示します。ファイル名を簡単にソートするために使用できます。
cut -f2
タブの後ろ部分のみを抽出します。
xargs head -n 1
各ファイルの最初の行を取得します。
cut -c1-3
各行の最初の3文字を表示します。
このhead -n 1
部分はパイプラインに必要です。それ以外の場合は、cut
各ファイルの各行の最初の3文字が表示されます。
答え3
GNUヘッド(用-q
)とシェルのデフォルトのワイルドカード拡張ソートを使用してください。
head -q -c 3 * > /tmp/output
または、
for file in *; do dd status=none if="$file" bs=1 count=3; done > /tmp/output
ファイルが単一のサブディレクトリにある場合(基準:あなたの別のコメント)次にワイルドカードを調整します。
head -q -c 3 /directory/subdirectory/* > /tmp/output
そして
for file in /directory/subdirectory/* # ...
答え4
だから私はついに答えからインスピレーションを得た独自のソリューションでこの問題を解決しました。 1つではなく3つのコマンドで実行する必要がありました。私はこれをしました:
mkdir holder
find . -type f -exec mv -t holder {} \;
head -qc 3 ./holder/* > prophetie.txt
これにより、文全体が必要に応じて左から右に流れます。私は
ls -l holder
それらはすべてアルファベット順になっています。これを行うときに並べ替える必要さえありません。 mvコマンドがソートしていると思いますか?